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), deploy_tree_invalid, embedded_secret (21-03), destructive_change_refused (23-02) (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), module_not_registered (16-01) |
| 4 | network | network_error, module_feed_unreachable (15-01), transport_failed (22-01) |
| 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), module_release_not_found, module_digest_mismatch, module_feed_unusable (15-01), module_digest_changed (15-02), module_uninstall_denied (19-01), scan_lock_held (20-02), resource_signature_rejected (20-02), resource_exists (20-REVIEW WR-01), mode_exists (20-REVIEW WR-01), deploy_ledger_invalid (22-03), plan_stale, deploy_blocked, deploy_preflight_failed, deploy_journal_present, deploy_live_changed, deploy_run_invalid, rollback_failed (23-02), project_git_managed (25-07), deploy_unreadable (quick-261029-ms3) |
| 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§
- Deploy
Finding - One defect in a declared deploy tree (21-03).
- Deploy
Tree Invalid Details - Payload of
CoreError::DeployTreeInvalid, boxed to keepCoreErrorunder clippy’sresult_large_errthreshold. - Embedded
Secret Details - Payload of
CoreError::EmbeddedSecret, boxed to keepCoreErrorunder clippy’sresult_large_errthreshold. Carries locations only: there is deliberately no field that can hold a secret value. - 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. - Module
Digest Changed Details - Payload of
CoreError::ModuleDigestChanged, boxed to keepCoreErrorunder clippy’sresult_large_errthreshold. - Module
Digest Mismatch Details - Payload of
CoreError::ModuleDigestMismatch, boxed to keepCoreErrorunder clippy’sresult_large_errthreshold. - Preflight
Failure - One failed apply preflight check (23-02).
detailcarries no value from the gateway, the host or the repo that could be a secret. - Rollback
Failure - Payload of
CoreError::RollbackFailed(23-02).
Enums§
- Core
Error - Every failure
igncan report. One variant per contract class;code(),exit_code(),hint()are total functions over it. - Signature
Reason - Why a resource write’s signature was refused
(
CoreError::ResourceSignatureRejected).
Constants§
- APPLY_
LIST_ SHOWN - Items listed inline by the Phase 23 refusal Displays; the rest collapse
into
and {m} more. - DEPLOY_
FINDINGS_ SHOWN - Findings shown inline by the deploy error Displays; the rest collapse
into
and {m} more. - 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. - TESTING_
ROUTE_ PREFIX - The TESTING bundle’s route prefix (QUICK-p0g). The
CoreError::RoutesNotDeployedhint is content-addressed off it — same third instance of the 06-07 pattern: the frozen taxonomy keeps ONE absent-routes variant and one slug (routes_not_deployed, exit 6), but the testing bundle installs through a DIFFERENT command (ign webdev deploy --with-testing/ign adopt --project NAME --testing), so the genericign webdev deployhint would name a command that does not fix it. Raise sites passroute: "testing/run". - TOP_
TTY_ REFUSAL_ REASON - The
ign top(itop) TTY-refusal reason — the SAME usage class and slug asTUI_TTY_REFUSAL_REASONat one command over (the monitor is its own full-screen surface, so its refusal names ITS command — the RoutesNotDeployed rule: a hint must never name a command that does not fix it).CoreError::hintcontent-addresses this constant exactly like its tui sibling. - 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.