Troubleshooting
A workspace boots a lot of moving parts: a local datastore, durable workflows, and one or more agents. This page catalogues the failures you are likely to hit, keyed on the
error.codestrings and exit codes the CLI emits, so you can branch on a single value instead of reading a stack trace.
The diagnostic loop
Every command supports the same four-step loop. Run it before anything else:
- Re-run with
--json. Errors come back as a structured envelope:{ "error": { "code", "message", "suggestion" } }. Thecodeis stable across releases and thesuggestionis the next command to try. - Map
codeto an exit code. Shell scripts can branch on$?instead of parsing text. See the full table at Configuration → Exit codes. - Escalate the logs. Set
STACKBONE_LOG_LEVEL=debugto surface the structured logs on stderr. When a boot stage hangs, escalate further with--verbose(orSTACKBONE_VERBOSE=1): that swaps the per-stage spinner UI for the raw firehose, including the container engine's own output, which shows why a stage is stuck. - Let your coding agent read these pages. Run
stackbone docsfor the connection details of the documentation MCP server. Once the agent is connected it searches this site by question and reads the page it needs, including this one.
Reading a boot failure
stackbone dev walks a fixed sequence of stages, and the spinner UI paints
one line per stage. The emulator stage is the exception: it runs in the
listed order but draws no line of its own, so a failure there arrives as the
error envelope rather than a red spinner.
| Stage | What it does |
|---|---|
docker |
Brings up the local datastore: Postgres, Redis and an S3-compatible store |
platform-migrations |
Applies the runtime's own schema |
creator-migrations |
Applies your workspace's schema (src/schema.ts → .stackbone/migrations/) |
emulator |
Starts the local control plane and begins serving |
tunnel |
Opens the public URL that fronts your local workspace |
workflows |
Compiles your durable workflows |
world |
Boots the durable workflow world (the worker that drains workflow runs) and mounts its routes |
deep-agents |
Bundles and registers every agent under deep-agents/ |
The order matters: everything Stackbone owns (the datastore, the schema, the control plane and the tunnel) comes up before the CLI compiles or runs anything you wrote. Even a workspace that cannot start yet leaves you with a reachable control plane and a working link.
The CLI discovers the workspace by convention: every folder under deep-agents/
with an index.ts is one agent, and every workflows/<name>.workflow.ts is
one durable workflow. Agents run in-process inside the control plane, and
there is no per-agent process to build or start, so a broken agent
(a bad import, a syntax error in its index.ts) fails the deep-agents stage
without taking the session down. When a stage fails, the spinner turns that
line red and the structured error tells you which one and why.
The CLI skips stages you do not use: no workflows means no workflows or
world line, and no deep-agents/ folder means no deep-agents line. The
tunnel stage always runs, because the public tunnel is mandatory.
stackbone dev failures
This directory is not linked to an agent
Symptom: stackbone dev exits before any stage runs with no_project and
"No project linked in this directory, and nothing here can ask which agent it
is."
Cause: the project has no .stackbone/project.json and this run cannot
prompt for one. .stackbone/ is gitignored, so a project cloned from someone
else's repository always arrives unlinked, and a run without a terminal (or one
with a CI environment variable, --yes or --json) has nobody to ask.
Fix: run stackbone dev once from a terminal and pick the agent. It writes
the link, and every later run reuses it, scripted or not. To link without a
prompt, write .stackbone/project.json yourself; stackbone agents get <slug>
prints the agent id it needs.
Reaching for stackbone init here is the common mistake: it registers a new
agent and scaffolds over the project you were handed. Full contract:
A project that arrived without a link.
Docker not running, or the datastore is unhealthy
Symptom: the docker stage fails, or platform-migrations /
creator-migrations fail with a connection or migration error.
Cause: the container engine is not running, or the local Postgres / Redis container is unhealthy.
Fix: make sure your container engine is running, then re-run
stackbone dev. When a migration stage fails, the CLI's suggestion points you
at the local container logs. Read them from the generated stack, then re-run:
cd .stackbone/dev && docker compose logs postgresPort already in use
Symptom: the emulator stage fails because its port is taken.
Cause: the local control plane defaults to port 4242 and something else
already holds it (often a previous stackbone dev that did not shut down).
Fix: free the port, or move the control plane with stackbone dev --port <n>.
Your agents run in-process inside that control plane, so its port is the only
one to relocate.
Nothing of yours started
Symptom: stackbone dev finishes, the emulator and tunnel are up, but the
workflows, world and deep-agents stages never ran. The CLI printed "Your
workflows and agents are not running yet".
Cause: the boot gate. This deployment has no model provider configured and nobody has been through the first run, so the boot held your code back rather than failing every agent that names a model.
Fix: open the Studio link the CLI printed and finish the guided setup. Your
workspace starts the moment you save, with no restart. If the link is
unreachable, export the endpoint and run stackbone dev again:
export MODEL_PROVIDER_BASE_URL=https://openrouter.ai/api/v1
export MODEL_PROVIDER_API_KEY=sk-... # omit for a keyless local gatewayFull contract: The first run.
An agent is waiting for a model provider
Symptom: the agent appears in Studio and in GET /api/discovery, but
Studio marks it degraded and chatting with it returns 503 instead of an
answer.
Cause: the agent declares its model as a bare id and no model provider resolved, so the runtime could not build its graph. This is a configuration gap.
Fix: configure a model provider (Studio's Model provider screen, or the environment variables above). Saving re-registers every degraded agent in place. An agent that stays degraded afterwards carries a different reason, which Studio shows on the agent's own screen.
An agent fails to build
Symptom: the deep-agents stage fails, with an error naming one of your
deep-agents/<name>/index.ts files, or "Cannot resolve esbuild from the
workspace".
Cause: you have not installed your project's dependencies, so the build
cannot resolve the agent runtime library (or its model provider packages), or
the agent's index.ts itself has a syntax or import error.
Fix: install your workspace dependencies (pnpm install from the
project root) so every agent can resolve its runtime library. The session stays
up while you fix it. Saving the file re-bundles that agent in place, with no
restart. If the error names a specific file, fix that agent and save.
"Failed to boot the workflow world"
Symptom: the world stage fails with this message.
Cause: you have not installed your project's dependencies, so the workflow runtime worker cannot boot.
Fix: install your workspace dependencies, then re-run stackbone dev.
A workflow will not start
Symptom: stackbone workflows list shows the workflow, but
stackbone workflows start <name> and POST /api/workflows/<name>/start come
back 503 with a reason instead of a run id.
Cause: that workflow failed to compile. A workflow build error leaves the
session and the sibling workflows running: the ones that compiled still serve,
and the CLI registers each broken one as degraded so the catalogue can still
name it. A degraded entry answers 503 with a reason. A typo in the name answers
404.
Fix: re-run with --verbose and look for the
Workflow "<name>" failed to build and is listed as degraded warning. The cause
follows it. Fix the file and save: the workflow watcher recompiles and remounts
the set in place. See Workflows for the authoring
contract behind the build.
No workflows at all
Symptom: stackbone dev starts fine, but stackbone workflows list and
stackbone runs list come back empty.
Cause: the workflows stage soft-failed before any workflow compiled, so
the session started without workflows and the control plane never mounted
the workflow routes. Your agents are unaffected.
Fix: re-run with --verbose and look for the
Workflow build failed, starting WITHOUT workflows warning. The cause follows
it. Fix the error and restart.
The tunnel will not open
The public tunnel is mandatory (there is no opt-out flag) so its grant flow is a common boot blocker. Four failures map to four error codes:
error.code |
Meaning | Fix |
|---|---|---|
auth_required |
No active session, or the control plane rejected it | Run stackbone login, then re-run |
workspace_tunnel_cap_reached |
Your workspace already has the maximum active tunnels | Stop another stackbone dev session, or wait for an existing grant to expire |
tunnel_relay_unhealthy |
The tunnel relay itself is down and cannot mint a grant | Check status.stackbone.ai and re-run once it recovers |
generic |
"frpc is not installed or not on PATH": the auto-fetch could not run |
Install frpc yourself and point STACKBONE_FRPC_BIN at it, see Using a system frpc binary |
The CLI retries tunnel_relay_unhealthy and generic on its own before the
command gives up, so a single flap costs you nothing. It does not retry
auth_required or workspace_tunnel_cap_reached, because a retry cannot fix
either one.
Native Windows shell
Symptom: the CLI refuses to start with a banner about unsupported shells
(error.code is unsupported_platform).
Cause: you are running from a native Windows shell (PowerShell or CMD), which lacks the unix utilities the dev boot relies on.
Fix: run the CLI from WSL2 or Git Bash instead.
Ctrl-C does not stop stackbone dev in Git Bash
Symptom: the dev session keeps running after Ctrl-C, and you have to close the terminal to stop it. Git Bash only.
Cause: older Git Bash terminals run the CLI without a real pseudo-terminal,
so the keystroke never reaches the process. The CLI re-launches itself under
winpty to fix that, and winpty is not on your PATH.
Fix: run winpty stackbone dev, or use Windows Terminal or WSL2, where
Ctrl-C already works. Every other command is unaffected: only dev is long
enough to need the interrupt.
Command-targeting failures
The Studio surface commands (runs, logs, workflows, hitl, config,
secrets and friends) target the local-dev installation of your project by
default, and a running cloud installation when you pass --agent <id>.
error.code |
Exit | Meaning & fix |
|---|---|---|
dev_not_running |
3 |
The command targeted your local-dev install but no stackbone dev is live. Start stackbone dev from this project, or pass --agent <id> to hit a cloud install instead. |
auth |
2 |
Not logged in or the session expired. Run stackbone login. |
not_found |
4 |
The targeted workspace, run or resource does not exist. |
permission |
5 |
You are authenticated but not allowed to act on that resource (also raised when a destructive verb runs without --yes). |
runtime_not_configured |
4 |
The --agent <id> you targeted has no registered deployment, so there is no runtime to answer. Deploy the box, then register it with stackbone link. |
dev_not_running is the most common surprise on this command surface: a
runs / logs / workflows command run in a project where nothing is live
fails fast with exit 3 rather than hanging. Start stackbone dev, or target a
cloud install with --agent.
The durable-workflow tooling (stackbone workflows list,
stackbone workflows schema) runs against stackbone dev today. Pointed at an
installation that does not serve the workflow routes, those commands come back
empty rather than erroring.
Incompatible @stackbone/sdk
@stackbone/sdk@<version> is not compatible with this CLI, which supports >=0.3.0 <0.4.0-0 (built against 0.3.1).
Each CLI build supports one minor line of @stackbone/sdk. stackbone dev
checks the version installed in your project on boot and warns when it falls
outside that line, then keeps the local loop running. Pin the SDK to a
supported version and reinstall:
pnpm add -E @stackbone/sdk@<version>If the SDK is not installed at all, the message tells you to run pnpm install
first instead. A scaffolded project pins the SDK exactly (no caret), so a stray
pnpm update cannot move it off the supported line.
Checking a deployed workspace's health
A running workspace exposes two probes you can hit directly when a deployment reports as degraded:
| Endpoint | Returns |
|---|---|
GET /live |
Instant 200, the process is up. Use it for liveness checks. |
GET /health |
Deep 200/503 with checks: { database, redis }, tells you which subsystem failed. |
When /health returns 503, read the checks object: database covers your
Postgres connection and redis covers the durable workflow backend. For the
durable-execution model behind these surfaces, see
Agents and the
Workflow SDK docs.
Keeping the CLI up to date
Two independent signals tell you the CLI is behind, one soft and one hard.
A newer release is out (soft). About once a day the CLI checks the npm
registry in the background and prints a short banner to stderr when it finds a
newer @stackbone/cli. It never blocks a command or changes an exit code.
Upgrade with the command the banner prints (it tracks your release channel, so a
prerelease install is told to upgrade on @alpha, never @latest). The banner
stays quiet on its own in --json mode, in CI, and when stdout is not a
terminal. Silence it everywhere with STACKBONE_NO_UPDATE_CHECK=1. See
Configuration → Environment variables.
Your CLI is no longer supported (hard). The control plane rejects a CLI
older than the minimum version it accepts. The failure comes back with
error.code cli_upgrade_required and exit code 1, and its suggestion
field carries the exact upgrade command to run. The control plane gates the CLI
only, and lets the dashboard, SDK clients and health checks through. Run the
suggested upgrade, then retry.
See also
- Configuration: the
--jsonenvelope and the exit-code table. - Local development: the full
stackbone devloop. - Commands: every command and its verbs.