error codes and exit codes
the nine stable error codes, each code's details shape and process exit code, the full exit-code table, and the wait-timeout vs agent-timeout distinction.
orcr has a deliberately small error enum: nine stable codes, with everything finer carried in details. adding codes later is easy; removing them is not. every --json error is {"ok":false,"error":{code,message,details}}, and the CLI maps each code to a process exit code.
the codes and exit mappings here come from
src/error.rsand are exposed in the schema underERROR_CODES(also exported by the SDK). each code has one SDK error class; see the SDK reference.
the nine codes
| code | exit | when | details |
|---|---|---|---|
not_found | 6 | a target resolved to nothing | {target, candidates?} (shortest disambiguating uuid prefixes when ambiguous) |
invalid_request | 1 | bad flags, names, durations, cron, frames, methods, or JSON | {field?, value?, reason} (for example reason: "path_too_deep") |
state_conflict | 7 | wrong state for the verb | {current_status, reason?}: reason: "force_required" for unmanaged kills, reason: "path_in_use" with the occupying {uuid, path, status} |
blocked | 4 | a waited agent needs a human | {blocked_kind} (question / limit / login / unknown) |
timeout | 3 | a direct command's own deadline expired | {elapsed} |
integration_missing | 2 | a provider is missing an integration layer | {provider, missing:[orcr|herdr], install} (the exact install command) |
transcript_unavailable | 1 | no final response is identifiable, including ambiguous or stale transcripts | {uuid, status, cause?} |
environment_error | 2 | server, store, herdr, home, platform, or version problem | {cause, …} (see below) |
server_error | 1 | internal failure (spawn, signal, cursor) | {cause, …} |
environment_error causes
environment_error covers the setup and platform failures. the cause field names the specific problem:
| cause | meaning |
|---|---|
herdr_unreachable | the server is fine but herdr is not (not discovered, or its socket is unreachable) |
server_start_failed | the server could not be spawned |
server_unreachable | a client could not connect to the socket |
store_locked | another process holds the store |
config_invalid | a known config key failed strict validation |
unsafe_home | ~/.orcr is not owned by the current uid, or is group/world-writable |
unsupported_platform | server enable/disable on a platform with no service unit |
unsupported_version | protocol version mismatch (orcr client to server, or server to herdr) |
the full exit-code table
exit codes come from two places: the error enum above (a failed command), and the outcome of wait and kill (which can exit non-zero without an error envelope). the complete set:
| code | meaning |
|---|---|
0 | success; for wait, every target settled successfully |
1 | other: invalid_request, transcript_unavailable, server_error |
2 | environment: integration_missing, environment_error |
3 | timeout: an agent's or run's own deadline; also a wait's own --timeout |
4 | blocked: an agent needs a human |
5 | killed / ended: a wait target died (killed, canceled, timeout, failed, or lost) |
6 | not found |
7 | state conflict (wrong state; force_required for unmanaged kills) |
exit code 5 is a command outcome, not an error code: it comes only from a wait observing a dead target (killed, canceled, timeout, failed, or lost). a kill never exits 5: a kill where every matched target is skipped (already ended, or needs --force) exits 7 (state_conflict), and a kill that matches nothing exits 6 (not_found). see the status model reference for how each observed state maps to a wait reason token and exit contribution.
wait-timeout vs agent-timeout
these look similar but are not the same:
- an agent's or run's own
--timeoutexpiring is thetimeouterror code (exit 3,details.elapsed). the agent is killed withexit_reason: timeout. awaitobserving it reports thetimeoutreason token (exit 5, because the target died). - a wait-style command's own
--timeoutexpiring is not an error. the envelope staysok:truewith a partial result (timed_out:true), and the process exits 3. the call succeeded; the targets just had not all settled. unsettled targets show thewait_timeoutreason token with their current status.
the single rule: ok:true + timed_out is a partial success; the timeout error code is reserved for a deadline the command itself set on an agent or run.
status, exit_reason, and wait tokens
the exhaustive tables: the managed and unmanaged status vocabularies, exit_reason groups, blocked_kind, and the status × exit_reason mapping to wait reason tokens with exit contributions.
path grammar and glob patterns
the one grammar every surface derives from (segments, paths, patterns, the rand placeholder, loop names, run ids), plus the anchored matching rules, reserved names, and resolution order.