vike

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 path
store:  /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 credentials

This 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:

  1. No vike-datahub is running. Start one next to the history store.
  2. It is running somewhere else. --addr defaults to 127.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 with ssh -L 7878:localhost:7878 <host> and leave the command line alone.
  3. 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 — turn tradehub_control on in its flags.toml and 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-status says 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.

On this page