When it goes wrong
The failures a real vike-cli install actually hits — a store that is not there, a data service that is not listening, a variable that no longer exists — and what each message is telling you.
Most vike-cli failures are one of three shapes, and all three are the binary telling you something
true about the box rather than about itself. This page takes them in the order a fresh install meets
them. The platform-wide symptom index is Troubleshooting; this page is the
CLI's own.
Two rules explain the dispositions below. Absent credentials are the live gate — a venue with no keys stays paper, silently, by design. And a misconfiguration splits two ways: refuse when a silent difference would leave you believing a protection is armed when it is not, degrade when "unconfigured" is a state you may legitimately have chosen.
no store found — every venue stays paper
vike-cli secrets pathstore: /srv/vike/settings/secrets.env (absent)
nothing here reads any other location — create it to configure a venue:
mkdir -p /srv/vike/settings
$EDITOR /srv/vike/settings/secrets.env
chmod 600 /srv/vike/settings/secrets.env # it is plaintext credentialsThis is the ordinary unconfigured state and it is deliberately not an error. What it usually means
on a box that is configured is that the walk resolved a different project than you expected: the
settings directory is found by walking up from the working directory, so the answer depends on
where you were standing. VIKE_SETTINGS_DIR names it outright and beats the walk. Nothing outside
that directory can supply a credential — no home directory is consulted under any variable.
Absent has three answers, not two
Path::exists maps every error to false, so a project root the process cannot search once
reported the store as absent and then printed the fresh-install advice for what was really a
permissions problem. crates/vike-cli/src/cmd/secrets.rs's Presence uses Path::try_exists
instead, and the third state prints words the other two share none of, because an operator greps
this line. It is a finding rather than a refusal: it names the path, says what was not established,
and still exits 0 — path is what you run when something is already broken.
A store that exists and cannot be read is a different problem again, and one the platform treats
as an error rather than as "no credentials": those two states looking the same downstream is exactly
how a permissions bug wears the fresh-install answer while every venue drops to paper. For the
node-facing verbs the read is non-fatal — the error is reported on stderr and the store treated as
empty, because an exported key must still work when that file is broken — while
vike-cli config check escalates it to a failure on a box armed for live, and leaves it a
warning on one that is not.
cannot connect to datahub at 127.0.0.1:7878
vike-cli backtest: cannot connect to datahub at 127.0.0.1:7878: Connection refused (os error 111)backtest, sweep and walkforward are clients. They compute nothing locally — the whole design is
that the profile's text crosses the wire and the tape does not — so with no server there is nothing
to fall back to. Three causes, in the order they happen:
- No
vike-datahubis running. Start one next to the history store. - It is running somewhere else.
--addrdefaults to127.0.0.1:7878; the server binds loopback and refuses a non-loopback bind unless it is explicitly allowed and a node key is set. Reach a remote one withssh -L 7878:localhost:7878 <host>and leave the command line alone. - The tunnel is up but the far end is not. A refused connection through a forward looks identical to a refused local one.
A transport failure and a server-side error both arrive as the same kind of failure on this side, so
read the message: a server that answered and refused says so in its own words. A profile with no
[sweep] table, or a walk-forward over a tick or multi-symbol profile, are clean server-side
errors rather than silent fallbacks.
The other half of "it connected and did nothing useful" is an empty store: a profile naming a slice
the store does not hold completes and reports no trades, which is indistinguishable from a
strategy that never fired. That is not an error anywhere, and it is why init's closing lines name
the seeding commands.
A removed environment variable refuses startup
vike-cli: VIKE_MAX_ORDER_NOTIONAL=250 is set, but VIKE_MAX_ORDER_NOTIONAL is NO LONGER READ —
removed in Phase 5 (settings unification), because an order-size ceiling any exported variable can
raise is not a ceiling.
Set it in <project>/settings/policy.toml instead:
max_notional_per_order = 250
then unset VIKE_MAX_ORDER_NOTIONAL.Every verb runs this check before dispatch, so secrets path fails on it exactly as trade does.
That is the point: a stale variable is stale regardless of what you typed, and quietly ignoring it
would let the box trade uncapped while the operator believed a ceiling was armed — worse than either
keeping the variable or refusing.
The message pastes back your own value when it is a value the key would accept, and a placeholder when it is not, so the suggested line always works. A variable whose value is itself a secret is named but never echoed. A present but empty value starts normally: it configured nothing under the old reader either, so nobody can believe a ceiling was active from one.
vike_config::REMOVED_ENV is the table, and it currently holds VIKE_MAX_ORDER_NOTIONAL,
VIKE_TRADEHUB_MAX_ORDER_NOTIONAL and VIKE_SECRETS_PASSPHRASE.
Node keys and scopes
vike-cli trade: no vike-tradehub node key found — nothing to do.
looked for VIKE_TRADEHUB_OBSERVE_KEY (read) and VIKE_TRADEHUB_CONTROL_KEY (write) in:
1. the process environment (a shell `export`, a systemd `Environment=`)
2. ...
set at least one to observe/control the node — `vike-cli secrets path` prints the store's location.The message names both places it looked, which the old one did not — it claimed the keys were
"not set in the environment" while the daemon's own keys sat unread in the credential store. If you
are sure the keys are there, vike-cli secrets list prints the names it can see in the store, and
secrets path prints which store that is.
Three more shapes are worth recognising because they look like a key problem and are not:
writes disabled: the node REFUSED the control scope at connect time. Your key is fine; it authenticated. The node is not accepting control connections at all — turntradehub_controlon in itsflags.tomland restart it.- A read verb refusing while a control key resolved. The node verifies each scope against its
own key, so a control key cannot authenticate a read.
strategy-statussays so explicitly rather than printing the generic "no key found", because the key is right there in the store is exactly what you would otherwise conclude. - The node advertised no strategy-verbs capability. That is a version gap refused on the client
side before anything is sent, so the fix is to upgrade that node's
vike-tradehub.
Usage errors that name the wrong token
The flag grammar refuses to let a valued flag eat another flag. vike-cli backtest --script --json
does not silently take --json as the script path; the error names the unfed flag and the token
it would have eaten. --profile with nothing after it is --profile requires a value, and
--json=1 is --json takes no value rather than a silent true. The test is --, not a bare -,
because a negative number is a real value — --qty -5 resolves to -5.
One class of message is not an error at all: a line like vike-cli: <file>: … about an indicator is
install_user_indicators reporting a user_data/indicators/*.rhai it could not compile. It goes to
stderr and never fails the command, deliberately — one half-edited indicator blocking every
invocation, including the init that scaffolds the examples, would be worse than the report. But
from inside a strategy that indicator is indistinguishable from a typo in the call, so this is the
only place that says which.
For the whole box rather than one verb, vike-cli config check judges the settings tree and the
credential store together and makes the verdict its exit code — see
Scripting it and config.
Scripting it
The machine-facing half — which verbs have --json and what each one emits, the two exit codes, the stdout/stderr split, and how to branch on all of it in a shell script.
vike-cli
The unified command-line surface — a subcommand dispatcher that resolves settings once, opens a credential only when a verb needs one, and answers --help on stdout with exit 0.