code and a one-line, actionable message. The CLI catches these and
renders just the message, exiting 1. Anything unexpected exits 2.
In code, errors are thrown by providers and detected with isAsymmetricError(e);
each carries a code you can switch on.
The errors
| Code | Message | What to do |
|---|---|---|
DOCKER_UNAVAILABLE | Docker isn't running. Start it, then retry. (asym doctor) | Start Docker Desktop / the daemon. |
NO_FREE_PORTS | No free ports in {from}-{to}. Destroy a clone or widen the range. | destroy an unused clone, or widen portRange in config.json. |
PORT_IN_USE | Port {port} is busy. | Free the port or let the allocator pick another. |
CLONE_START_FAILED | {id} failed to start. See logs: asym logs {id} | Check asym logs <id> for the underlying failure. |
HEALTH_TIMEOUT | {id} didn't become healthy in {seconds}s. See logs: asym logs {id} | The backend started but never passed its health check — inspect logs. |
SCHEMA_MISSING | {id} has no schema yet. Migrations will run before seeding. | Informational — migrations run before the seed. |
SEED_VALIDATION | {rejected} generated record(s) were rejected by validation. | Some AI records failed the clone’s validation; usually safe to ignore or re-seed. |
LLM_UNAVAILABLE | AI seeding is degraded. Retry with: asym seed | Check ANTHROPIC_API_KEY and connectivity, then retry. |
CONTROL_PLANE_DOWN | Control plane unreachable. Working locally, will sync later. | Connected mode only — the CLI keeps working locally. |
DOCS_FETCH_FAILED | Couldn't fetch live {product} docs. Showing last known fidelity. | verify only — live docs were unreachable; cached score shown. |
CLONE_NOT_FOUND | Unknown clone "{id}". List clones: asym status | Check the id with asym status. |
TEMPLATE_NOT_FOUND | Unknown template "{template}". List templates: asym ls --templates | Check the template name. |
REGISTRY_CORRUPT | Local registry is corrupt. Rebuild it with: asym doctor | Run asym doctor to recover. |
ENV_SPEC_INVALID | {what's wrong with the environment.yaml} | env spin only — fix the spec: a typo’d key, a missing field, or a not-yet-supported section (identity or data). The message says exactly what. |
Image & registry errors
Clone backends ship as published images that the CLI pulls (and verifies) at spin time. These cover everything that can go wrong fetching one.| Code | Message | What to do |
|---|---|---|
REGISTRY_UNREACHABLE | Can't reach the image registry for {image}. Check your network and retry. | Network/DNS/TLS failure reaching the registry. A previously-cached image still runs. |
IMAGE_NOT_FOUND | Image "{image}" was not found. Check the tag, or run: asym upgrade | The tag doesn’t exist — check the ref, or asym upgrade to repin. |
REGISTRY_AUTH | Access denied pulling "{image}". The package should be public — check the ref, or 'docker login'. | The package is public, so this usually means a typo’d ref; otherwise docker login. |
IMAGE_PULL_FAILED | Couldn't pull "{image}". Retry, or check Docker has registry access. | A pull failed for another reason (partial layer, daemon error) — retry. |
IMAGE_DIGEST_MISMATCH | The pinned image for this clone ({image}) is gone. Repin with: asym upgrade | The pinned digest was withdrawn (:latest re-tagged) — run asym upgrade to repin. |
IMAGE_VERIFICATION_FAILED | Image "{image}" failed signature verification — refusing to run it. | Fails closed — the image is unsigned or tampered; re-pull a genuine image. |
Exit codes
| Code | Meaning |
|---|---|
0 | Success. |
1 | A known AsymmetricError (one of the above), or a per-template failure during spin. |
2 | Bad invocation (e.g. query with no SQL, or --json + --write) or an unexpected error. |
Design intent
The error map is part of the contract, not an afterthought. Each failure mode in the system has exactly one named error with a stablecode and a userMessage,
so the same failure reads the same way everywhere and tools can switch on the
code. If you’re building a provider or a template, throw these — never a bare
Error.