All docs ▾

Docs / Reference / Troubleshooting

Troubleshooting#

Docker, WSL2, slow pulls, locked bridges, and the clean-slate warning.

On this page

The problems people actually hit, and the ones that look like bugs but are the product working as designed. If yours isn’t here, the main-process log is the next stop: it’s at the bottom of this page.

Docker won’t start, or Compose is too old.#

Vex runs its database and embeddings locally, in containers it manages for you, so Docker is not optional. Three variants of the same failure:

  • Docker missing. The app probes for it at startup and offers to help: on macOS and Windows it downloads the Docker Desktop installer to your Downloads folder and opens it, and on Linux it hands you a copy-paste block for your distribution. It never elevates privileges for you. Install it, then relaunch Vex and the bootstrap resumes.
  • Compose too old. The floor is Compose 2.23.1, because the compose template uses an inline configs: content: block that older versions reject with an obscure unknown field: content. The System Check screen detects this and shows an upgrade hint rather than letting you hit the cryptic failure.
  • Windows without the WSL2 backend. Docker Desktop on Windows must have the WSL2 backend enabled. The Hyper-V backend has bind-mount path bugs that Vex does not test against.

Full platform and version detail is in Requirements.

The first run takes forever.#

Expected. The first compose-up pulls the container images and then downloads the local embedding model, about 333 MB, which can take 5-15 min on a slow network. The download is checked against a pinned SHA256 and kept in a named Docker volume, so it happens once rather than every launch, and a cached copy whose checksum does not match is thrown away and fetched again. Progress is streamed into the bootstrap screen; leave it running rather than restarting the app.

Ubuntu minimal: install xdg-utils.#

Opening external links from inside the app goes through xdg-open. A standard Ubuntu desktop install ships it, but minimal and headless installs may not.

sudo apt-get install -y xdg-utils

Robinhood Chain balances look wrong.#

Balance scans on Robinhood Chain cover a pinned token set. Tokens you acquire through your own swaps and bridges are pinned automatically, but a token that arrived by airdrop or a plain transfer is not, and it will not show up until it is. Ask the agent to track it (WalletTrackToken) and it will appear in balances and in the Book from then on. This is a coverage limit of the balance scan, not a missing balance on-chain: Robinhood Chain is read direct from RPC because the bridge provider’s balance coverage excludes it.

“It re-quoted before executing”#

Also by design. The Safety Contract requires a swap or bridge to execute only against a fresh quote from the same venue, taken in the same turn, and the runtime enforces that rather than merely asking the model for it. A quote from an earlier turn, or from a different provider, is refused: stale pricing is how agents accidentally execute at numbers you never saw. The approval card you get always corresponds to the quote directly above it. See Approvals & the Safety Contract.

Vex Studio: locked vs not running#

The MCP listener starts only after you unlock Vex and the Studio readiness barrier reports ready, and locking the app closes it again. A self-custodial wallet does not leave a door open when nobody is home. The vex-mcp bridge does not retry and does not guess: it prints one line to stderr and exits with a code that is specific to the failure class, so your coding agent can tell you which of these it is.

Exit codeWhat it meansWhat to do
0Clean exit: help printed, or the session ended normally.Nothing to fix.
1Bad flags, or no project id (--project or VEX_PROJECT_ID).Use the command Vex shows for the project; the id is filled in.
2The bridge refused to dial: a malformed endpoint override, a directory on the path changed, or on Windows the pipe belongs to another user.The message names which; fix that, or sign in as the user running Vex.
3The dial reached the OS and failed: nothing listening, refused, permission error, timeout, or on Windows every pipe instance stayed busy.Start Vex, or check the client and Vex use the same config directory.
4The handshake could not be sent or its reply could not be read.Usually transient. Connect again.
5Unknown project: the host does not recognize the id.Open Vex, select the project, copy its MCP command again.
6Incompatible version: Vex speaks a different handshake version than this bridge.Update whichever is older.
7Vex locked: the vault is locked, or the runtime is not ready yet.Unlock Vex and connect again.
8At capacity: 16 connections, or 4 mid-handshake, already held.Close an idle MCP client and connect again.
9The host rejected the handshake as malformed.Treat it as a version skew: update the older side.
10The host refused with a code this bridge build does not know.Update the bridge.
11The relay failed mid-session: stdout or the socket went away.Reconnect; the session is not recoverable.
12Stopped by a signal (ctrl-c or the client tearing the process down).Expected.

Every stderr line is one sentence prefixed vex-mcp:. The bridge never retries on its own; reconnecting means re-running the command your client already has.

An approval raised by an external agent waits up to 1 hour, and the installer writes a longer tool-call timeout into each client’s own config so the call survives that window instead of dying first. See Studio approvals & scope.

Switching the embedding model#

Vectors already in your database were produced by the old model, so changing EMBEDDING_MODEL or EMBEDDING_DIM in place would leave memory searching against embeddings that no longer mean the same thing. Use the knowledge portability workflow instead:

  1. Export

    Run make knowledge-export to write your knowledge entries out in a model-independent form.

  2. Reconfigure

    Change the embedding model and dimension. They must match: when the model returns a vector of a different length than EMBEDDING_DIM, the client refuses by name instead of storing it, and that mismatch is the most common cause of a broken re-import.

  3. Import or re-embed

    Run make knowledge-import to load the export back. make knowledge-reembed is the in-place option and works only at the same dimension; if the configured dimension differs from what is already stored, it refuses and tells you to export, wipe and import instead.

Starting over from a clean slate#

This deletes your keys. Your config directory holds the only copies of your keystores, your encrypted vault and your backups. Removing it is irreversible: no custodian has a copy, because that is the whole point of the product. Export your keystores and copy backups/ somewhere safe before you delete anything. Exported keystores stay encrypted under your master password, so keep that too: losing it loses the vault and the keystores with it.

With backups exported, a clean slate is: quit Vex, bring down the install’s Docker Compose stack, then remove the config directory for your platform.

# Linux (or $XDG_CONFIG_HOME/vex if you set it)
rm -rf ~/.config/vex

# macOS
rm -rf ~/Library/Application\ Support/vex

# Windows (PowerShell)
Remove-Item -Recurse -Force $env:APPDATA\vex

The next launch starts at the first-run wizard again. See First run, and Wallets & custody for exporting and restoring keys.

Where the log lives#

The main-process log is inside your config directory at .electron-state/logs/main.log, for example ~/.config/vex/.electron-state/logs/main.log on Linux. It rotates at 5 MB. Paths for the other platforms are in Configuration.

Every line is written through a redacting logger, so secrets are scrubbed before any transport sees them, and unhandled errors are routed through the same redactor rather than bypassing it. The in-app report-issue dialog applies the same redaction to what you type before the report is stored locally.