Expand description
Typed error taxonomy — THE exit-code contract for ign.
The mapping error-class → exit code is LOCKED (Phase-1 API freeze). The
table exists in exactly two places: CoreError::exit_code here and the
README — kept in sync by the exit_code_mapping_enumerated unit test and
the golden-file tests in crates/ignition-cli/tests/.
| exit | class | slugs |
|---|---|---|
| 1 | internal | internal |
| 2 | usage | confirmation_required, invalid_import_file, invalid_input, gateway_client_error (09-01) (clap renders its own usage errors — never hook clap) |
| 3 | config | profile_not_found, no_active_profile, secret_unavailable, config_invalid, poll_interval_too_small (08-01) |
| 4 | network | network_error |
| 5 | auth | auth_rejected |
| 6 | target_state | gateway_too_old, gateway_not_commissioned, gateway_restarting, not_found, project_exists, resource_binary, trial_not_expired (04-03), provider_not_found (05-04), routes_not_deployed, webdev_unlicensed, route_version_mismatch, webdev_route_error (05-03), tag_collision (05-05), alarm_journal_missing (05-06), import_denied (05-07), session_not_prunable (06-07), eam_not_controller (07-02), eam_task_type_refused (07-02), eam_task_in_flight (07-06), script_exec_not_configured (07-03), lint_tool_absent (07-04), provider_root_unsupported (07-06), bundle_not_available (09-07) |
| 7 | rig | rig_error (reserved — first used in Phase 4) |
Slugs are public contract: never respell them. Exit codes are public contract: never renumber them (the enumerated test guards both).
Structs§
- Error
Body - LOCKED error body:
code(stable slug),message(human-readable),endpoint(when a request was involved),hint(actionable next step). - Error
Envelope - LOCKED failure envelope shape: exactly the top-level fields
ok,profile,error— changing the set is a breaking change for agents.
Enums§
- Core
Error - Every failure
igncan report. One variant per contract class;code(),exit_code(),hint()are total functions over it.
Constants§
- GATEWAY_
CLIENT_ BODY_ CAP_ BYTES - The api-call catch-all’s body cap (09-01): a gateway 4xx body rides
CoreError::GatewayClientErrorVERBATIM up to this many bytes; a larger body is truncated attruncate_api_bodywith the explicitGATEWAY_CLIENT_BODY_TRUNCATION_MARKER. 4 KiB is the plan-locked cap — an unbounded passthrough would let a pathological gateway page flood the agent’s envelope. - GATEWAY_
CLIENT_ BODY_ TRUNCATION_ MARKER - The truncation marker
truncate_api_bodyappends when the api-call body exceedsGATEWAY_CLIENT_BODY_CAP_BYTES. ASCII-pinned (no multi-byte characters) so golden-file consumers never see an encoding surprise at the cut. - LOSS_
GATE_ REFUSAL_ REASON_ PREFIX - The TAGS-12 loss-gate refusal reason prefix (11-07 gap closure). The
InvalidInput hint is content-addressed off this literal: the loss
gate’s reason is DYNAMIC prose (the CLI’s
render_loss_proseheaderloss report ({label}): …plus per-fact lines), so unlikeTUI_TTY_REFUSAL_REASONthe sentinel cannot be the whole reason — it is the stable header prefix instead. Same slug (invalid_input), same exit 2 (frozen taxonomy; only the hint differs) — the 06-07 TTY-refusal pattern at one removal. The contract_tags loss-gate pins are the drift guard: if the prose header ever changes, the hint silently regresses to the generic default and those pins fail. - TUI_
TTY_ REFUSAL_ REASON - The
ign tuiTTY-refusal reason (06-07). The InvalidInput hint is content-addressed off this exact string: the frozen taxonomy keeps ONE usage-input variant (no hint field, no new variant), but the TTY refusal’s fix is terminal-related, not--file/stdin —CoreError::hintspecial-cases this one reason while every other raise site keeps the resource-put default. Construct viaCoreError::tui_tty_refusalso the reason/hint pair cannot drift.
Functions§
- truncate_
api_ body - The ONE construction site for a capped api-call body: returns
bodyverbatim when it fitsGATEWAY_CLIENT_BODY_CAP_BYTES, otherwise its first cap bytes (on a UTF-8 char boundary) plusGATEWAY_CLIENT_BODY_TRUNCATION_MARKER. The variant always carries its final form — construction cannot forget the cap.