Exit codes and error taxonomy
Process exit code mappings, failure domains, and machine-readable error categories.
Invariant 3 states: Subprocess correctness is decided by exit codes only; parsed output enriches the UI.
exocomp maps subprocess and daemon failure states to deterministic exit codes.
Process exit codes
Process exit codes provide deterministic signals for automation and agents (Invariant 3).
| Code | Constant | Meaning | Source Sentinels / Context |
|---|---|---|---|
0 |
ExitOK |
Success | Clean completion, zero errors |
1 |
ExitFailure |
Generic failure | Run settled failed, tool error, or request failure |
2 |
ExitChangesPresent |
Changes present | OpenTofu plan detected changes (-detailed-exitcode 2) |
3 |
ExitNotFound |
Not found | Entity does not exist (store.ErrNotFound) |
4 |
ExitAuth |
Auth failure | Unauthenticated (CodeUnauthenticated) or forbidden (CodeForbidden) |
5 |
ExitConflict |
Conflict / Concurrency | State conflict (ErrStateConflict), lock held (ErrConcurrencyHeld), stale plan (ErrStalePlan) |
6 |
ExitAwaitingApproval |
Awaiting approval | Gated write or mutation landed pending human sign-off |
7 |
ExitBusy |
Transient busy | Auth KDF saturated (CodeKDFBusy) or SSE stream cap reached (CodeStreamsOverCap) |
Error envelopes and code taxonomy
When invoked with --output json, failures are emitted as RFC 9457-shaped envelopes with a top-level kind: "error" and a schema version:
{
"schema_version": 1,
"kind": "error",
"error": {
"code": "concurrency_held",
"message": "workspace 'network' is locked by job_01j7abc...",
"hint": "another run holds this workspace; wait for it to finish or cancel it"
}
}
The error codes map 1:1 onto internal store, reactive, and auth sentinels:
| Error Code | Sentinel / Condition | Actionable Hint |
|---|---|---|
not_found |
store.ErrNotFound |
Check the ID or name; list the collection to see what exists |
conflict |
store.ErrStateConflict |
Re-read entity state; the transition requested is not legal |
duplicate |
store.ErrDuplicate |
Name or key is already taken; choose another or remove existing |
concurrency_held |
store.ErrConcurrencyHeld |
Another run holds this workspace; wait for it to finish or cancel it |
stale_plan |
reactive.ErrStalePlan |
Workspace moved since plan was saved; re-plan before applying |
kdf_busy |
web.ErrKDFBusy |
Auth gate is saturated; retry shortly |
streams_over_cap |
CodeStreamsOverCap |
Too many live streams; close a tab or retry shortly |
unauthenticated |
web.ErrUnauthenticated |
Supply a valid token or session |
forbidden |
CodeForbidden |
Token scope is too low for the verb; mint one with higher scope |
internal |
CodeInternal |
Fallback for unexpected internal errors |