Skip to content
v0.3

Errors and refusals

Every command answers with the same 6 codes, and every surface maps them: the API returns the HTTP status below, the CLI exits non-zero and prints the code, MCP returns a tool error carrying it, and the SDK returns { ok: false, error } — it does not throw, so a refusal is a value the type system makes you handle rather than an exception you can forget to catch. The set is frozen; a caller can branch on it.

A refusal is not a failure. forbidden and conflict are the kernel telling a caller something true about power and about state; only internal means something went wrong.

CodeHTTPWhat it means
conflict409The command was understood and the state will not have it: a uniqueness already taken, a transition the entity cannot make from where it is. Retrying the same call unchanged produces the same answer.
forbidden403The credential is valid and does not carry the scope this command requires. It is a refusal about POWER, not about identity — a different token, not a retry.
internal500The kernel failed. Nothing was committed — a command is one transaction, so a failure leaves no half-applied write behind.
unauthorized401No usable credential. The token was absent, malformed, expired, or belongs to a generation that has been revoked.
unknown_command404No command by that name. Names are the contract and they are generated onto every surface at once, so this means the name is wrong or the kernel is older than the caller.
validation_failed400The input did not match the command’s schema. details carries the offending paths — the same schema published on the command’s own page, so a caller can check before sending.