Skip to main content

CoreError

Enum CoreError 

Source
pub enum CoreError {
Show 65 variants Internal(String), ConfirmationRequired { operation: String, }, ProfilingRiskNotAccepted { operation: String, }, InvalidImportFile { reason: String, }, ImportDenied { project: String, problem: String, endpoint: Option<String>, }, InvalidInput { reason: String, }, ProfileNotFound { name: String, known: Vec<String>, }, NoActiveProfile, SecretUnavailable { profile: String, }, PasswordUnavailable { profile: String, }, ConfigInvalid { reason: String, }, PollIntervalTooSmall { profile: String, }, Network { url: String, source: Option<Error>, observation: Option<String>, }, Auth { status: u16, endpoint: Option<String>, }, GatewayTooOld { found: String, minimum: String, endpoint: Option<String>, }, GatewayNotCommissioned { endpoint: Option<String>, }, GatewayRestarting { endpoint: Option<String>, }, NotFound { endpoint: Option<String>, }, ProjectExists { name: String, endpoint: Option<String>, }, ResourceBinary { path: String, endpoint: Option<String>, }, TrialNotExpired { remaining_s: i64, endpoint: Option<String>, }, RoutesNotDeployed { project: String, route: String, endpoint: Option<String>, }, WebdevUnlicensed { endpoint: Option<String>, }, RouteVersionMismatch { route: String, deployed: String, expected: String, endpoint: Option<String>, }, ProviderNotFound { name: String, endpoint: Option<String>, }, WebdevRouteError { code: String, message: String, endpoint: Option<String>, }, TagCollision { provider: String, names: Vec<String>, endpoint: Option<String>, }, AlarmJournalMissing { endpoint: Option<String>, }, SessionNotPrunable { id: String, endpoint: Option<String>, }, Rig(String), EamNotController { endpoint: Option<String>, }, ProviderRootUnsupported { endpoint: Option<String>, }, EamTaskTypeRefused { task_type: String, }, EamTaskInFlight { task: String, detail: String, endpoint: Option<String>, }, ScriptExecNotConfigured { profile: String, }, LintToolAbsent, NodeToolAbsent { tool: String, }, GatewayClientError { status: u16, endpoint: String, body: String, }, BundleNotAvailable { state: String, }, ModuleFeedUnreachable { url: String, source: Option<Error>, }, ModuleReleaseNotFound { module: String, version: String, url: String, detail: String, }, ModuleDigestMismatch(Box<ModuleDigestMismatchDetails>), ModuleFeedUnusable { url: String, detail: String, }, ModuleDigestChanged(Box<ModuleDigestChangedDetails>), ModuleNotRegistered { id: String, known: Vec<String>, }, ModuleUninstallDenied { module_id: String, gateway_module_id: String, failed: Vec<String>, endpoint: Option<String>, }, ScanLockHeld { actor: Option<String>, kind: String, endpoint: Option<String>, }, ResourceSignatureRejected { name: String, reason: SignatureReason, endpoint: Option<String>, }, ResourceExists { name: String, endpoint: Option<String>, }, ModeExists { name: String, endpoint: Option<String>, }, DeployTreeInvalid(Box<DeployTreeInvalidDetails>), EmbeddedSecret(Box<EmbeddedSecretDetails>), TransportFailed { operation: String, node: String, detail: String, }, DeployLedgerInvalid { location: String, problem: String, }, PlanStale { expected: String, actual: String, detail: String, }, DestructiveChangeRefused { gate: String, keys: Vec<String>, count: usize, }, DeployBlocked { keys: Vec<String>, }, DeployPreflightFailed { failures: Box<[PreflightFailure]>, }, DeployJournalPresent { run_id: String, env: String, location: String, }, DeployLiveChanged { run_id: String, paths: Vec<String>, count: usize, }, DeployRunInvalid { run_id: String, problem: String, }, RollbackFailed(Box<RollbackFailure>), ProjectGitManaged { project: String, location: String, kind: String, }, ProjectParentInvalid { project: String, parent: String, reason: String, }, ProjectHashMismatch { project: String, expected: String, actual: String, },
}
Expand description

Every failure ign can report. One variant per contract class; code(), exit_code(), hint() are total functions over it.

Variants§

§

Internal(String)

Unexpected runtime failure — the catch-all; report as a bug. Exit 1.

§

ConfirmationRequired

Destructive operation invoked without --yes. Exit 2 (same class as usage: it names a flag the caller must add; clap renders its own usage errors with its exit 2 — never hook clap).

Fields

§operation: String
§

ProfilingRiskNotAccepted

JVM profiling invoked without --i-accept-the-risk. Exit 2 (usage class — it names a flag the caller must add, like Self::ConfirmationRequired) but DELIBERATELY NOT satisfiable by the global --yes/IGNITION_YES: active JVM instrumentation is a stronger opt-in than the destructive-verb guard — the caller must acknowledge THIS specific production risk, not confirm generically.

Fields

§operation: String
§

InvalidImportFile

An import byte source the caller must fix (wrong file, too big, unreadable). Exit 2 — usage class: it names what the CALLER must change, like Self::ConfirmationRequired (03-02).

Fields

§reason: String
§

ImportDenied

The gateway ANSWERED the import POST with HTTP 200 but the body says {"success": false, "problem": "…"} — the denial-rides-200 class the WebDev family handles (05-01) applied to the project-import family (05-07, UAT Gap 1): without this check the import caller reports ok while nothing landed. Exit 6 — target state: the gateway refused the import (the problem text names why, verbatim).

Fields

§project: String

The project the import was headed for.

§problem: String

The gateway’s own problem text (verbatim when present).

§endpoint: Option<String>

URL of the import request, when known.

§

InvalidInput

A command input the caller must fix (unreadable --file, failed stdin read). Exit 2 — usage class, the generic sibling of Self::InvalidImportFile (03-03: resource put’s byte source).

Fields

§reason: String
§

ProfileNotFound

Named profile absent from config. Exit 3.

Fields

§name: String
§known: Vec<String>
§

NoActiveProfile

No --profile, no IGNITION_PROFILE, no active profile in config. Exit 3. Constructible from the CLI once config resolution lands (01-03); the taxonomy is complete on day one.

§

SecretUnavailable

No credential resolvable for the profile (env, token_env, keyring all missed or failed). Exit 3.

Fields

§profile: String
§

PasswordUnavailable

The adopt bootstrap’s login rung needs IGNITION_PASSWORD and it was absent/empty (ADOPT-05 review round: the generic Self::SecretUnavailable hint names the TOKEN paths, which is exactly wrong for the PASSWORD gate — same exit class, own slug, never a new exit code; the PollIntervalTooSmall precedent).

Fields

§profile: String
§

ConfigInvalid

Config file unreadable or wrong shape. Exit 3.

Fields

§reason: String
§

PollIntervalTooSmall

A profile’s poll_interval_secs is below the 1-second floor (08-01, TUIX-05 clamp): sub-second gateway polling is refused at load time — the TUI’s background refresh cadence may not hammer the gateway. Exit 3 — the CONFIG class (the Phase-7 additive-slug precedent, e.g. eam_not_controller: same exit class, own slug, never a new exit code — the 1–7 taxonomy is frozen).

Fields

§profile: String

The profile carrying the refused value.

§

Network

Gateway unreachable / timeout / TLS failure. Exit 4.

source: None marks a POLL deadline expiry (02-04 poll.rs): same class, same slug (network_error), no new variant — the transport-error source a real failure carries is simply absent, and url describes what was being waited on instead (the poll’s subject). The deadline’s last observation rides observation (09-07): when it is Some the gateway ANSWERED with a concrete state, and the message leads with “no terminal state” — it NEVER claims unreachability for an observed answer; None keeps the plain unreachability wording.

Fields

§source: Option<Error>
§observation: Option<String>

The poll deadline’s last concrete observation (e.g. the gateway’s reported state) — None for transport failures and observation-less deadlines. Some ⇒ the gateway answered; the Display never says “unreachable” then.

§

Auth

Gateway reachable but rejected credentials (401/403). Exit 5.

Fields

§status: u16
§endpoint: Option<String>

URL/path of the request that was rejected, when known.

§

GatewayTooOld

Gateway reachable but the command is invalid for its current state — version below minimum, uncommissioned, mid-restart, or a missing resource. Exit 6.

Fields

§found: String
§minimum: String
§endpoint: Option<String>

URL/path of the request that answered, when known.

§

GatewayNotCommissioned

Gateway reachable but uncommissioned — every /data route 302s to /welcome (verified on a fresh 8.3.6 container; 02-RESEARCH §Error-Body Sniffing). Exit 6.

Fields

§endpoint: Option<String>

URL that was redirected to the commissioning wizard.

§

GatewayRestarting

Gateway restarting — webserver answers (503) but services are down (verified restart lifecycle: webserver never drops the connection). Exit 6.

Fields

§endpoint: Option<String>

URL that answered 503.

§

NotFound

Named resource absent (404) — terminating a nonexistent session id, an unknown path, or a pre-8.3 gateway’s JSON {"message": "No route match for path: …"}. Exit 6.

Fields

§endpoint: Option<String>

URL that answered 404.

§

ProjectExists

A project of this name already exists and the import’s collision policy is abort — the CLI-side pre-check refused BEFORE any upload (the server’s own answer remains the backstop). Exit 6 — target state: the command is invalid for the gateway’s current state (03-02, the GatewayTooOld action-built-variant precedent: constructed by the actions layer, not classify).

Fields

§name: String

The colliding project name.

§endpoint: Option<String>

URL of the pre-check request, when known.

§

ResourceBinary

A binary (data.bin-class) resource met the surgical JSON/text loop — REFUSED rather than corrupted through it. Exit 6 — target state: the command is invalid for that resource’s nature; the export/import family owns binary resources (Pitfall 7).

Fields

§path: String

The resource path that was refused.

§endpoint: Option<String>

URL of the request involved, when known.

§

TrialNotExpired

The gateway refuses trial resets while the trial is still active — live-discovered on 8.3.3 during 04-03’s spike: the reset POST answers 403 on a NON-expired trial (verified from the browser page itself with the exact UI headers), and 200 + the flip on an expired one. The action layer’s expiry pre-check turns that misleading auth-shaped 403 into the honest target-state refusal. Exit 6 (the ProjectExists precedent: action-constructed, not classify).

Fields

§remaining_s: i64

Seconds left on the active trial.

§endpoint: Option<String>

URL of the rig’s trial endpoint, when known.

§

RoutesNotDeployed

The WebDev route family a command depends on is not deployed — the presence probe answered 405, the live-proven 8.3 absent marker (missing routes AND missing projects both answer 405, NOT 404; 05-RESEARCH Pitfall 1). Exit 6 — target state: the command is invalid until ign webdev deploy installs the routes (the TrialNotExpired precedent: action-constructed, not classify).

Fields

§project: String

The deploy project the probe targeted.

§route: String

The route folder the probe named.

§endpoint: Option<String>

Path of the probe request, when known.

§

WebdevUnlicensed

The WebDev module answered 402 — installed but unlicensed (a trial-expired gateway; live-verified cross-version on 8.3.6, 05-RESEARCH §Servlet). Exit 6 — no /system/webdev route can answer until the gateway is licensed.

Fields

§endpoint: Option<String>

Path of the probe request, when known.

§

RouteVersionMismatch

A deployed route’s handshake version differs from the embedded bundle’s — the CLI refuses rather than auto-upgrading either side (roadmap-locked: actionable error, no auto-upgrade magic). Exit 6.

Fields

§route: String

The route folder that answered.

§deployed: String

The route’s deployed routeVersion.

§expected: String

The embedded bundle’s version (crate::webdev::ROUTE_BUNDLE_VERSION).

§endpoint: Option<String>

Path of the probe request, when known.

§

ProviderNotFound

A tag provider of this name does not exist — the find→signature→delete chain’s find half missed (05-04, TAGS-01). Exit 6 — target state: the named thing is absent (the ProjectExists precedent family: action-constructed, not classify — the honest, family-specific refusal over a bare 404).

Fields

§name: String

The provider name that missed.

§endpoint: Option<String>

URL of the find request, when known.

§

WebdevRouteError

A WebDev route answered HTTP 200 with a body denial ({ok:false, error{code,message}}) whose machine code this CLI does not specifically map — code + message ride verbatim so agents can branch on the stable route contract (05-01). Exit 6 — target state: the deployed route refused the action.

Fields

§code: String

The route’s machine error code (stable contract).

§message: String

The route’s human message.

§endpoint: Option<String>

Path of the request, when known.

§

TagCollision

A tag import under abort policy found EXISTING tags at the target provider (05-05, TAGS-09) — the browse pre-check refuses BEFORE any route write (the LOCKED Phase-3 collision matrix mapped onto configure’s ‘a’/‘o’). Exit 6 — target state: the named tags exist; overwrite is the explicit, guarded opt-in.

Fields

§provider: String

The target provider the import was headed for.

§names: Vec<String>

The colliding top-level tag names the pre-check found.

§endpoint: Option<String>

URL of the pre-check browse request, when known.

§

AlarmJournalMissing

The gateway has no alarm-journal profile configured — alarm history has nowhere to read from. The alarms route’s structured no_alarm_journal denial maps here (the denial_to_error seam, 05-06 TAGS-07): DEFAULT rigs hit this ALWAYS, because the journal is a config-resource chain — database connection + ignition/alarm-journal profile + the general-alarm-settings singleton pointing at it. Exit 6 — target state: the command is invalid for the gateway’s current state until that chain is provisioned (the honest, actionable refusal over a bare route error).

Fields

§endpoint: Option<String>

URL of the alarms route request, when known.

§

SessionNotPrunable

Pruning a LIVE Designer session entry — the gateway’s prune route answers 409 (empty body, wire-verified on 8.3.3, 06-UAT test 6): prune removes STALE entries only, so the command is invalid while the Designer is still open. Exit 6 — target state (additive slug in the frozen taxonomy’s established growth pattern; classify()’s ROUTE-SCOPED 409 arm constructs this — the first classify-constructed refusal added since the 02-01 set).

Fields

§id: String

The Designer session id that was refused.

§endpoint: Option<String>

URL of the refused DELETE, when known.

§

Rig(String)

Docker/compose rig failure. Exit 7. Reserved — first used in Phase 4; trivially constructible so the taxonomy enumerates completely today.

§

EamNotController

The gateway’s EAM module is not configured as a controller — every /data/eam/api/v1/* runtime endpoint answers 403 with “This operation can only be performed when EAM is configured as a controller” on a stock gateway (live-proven 8.3.3, 07-RESEARCH): a STATE refusal, not auth — the token is fine, the module’s role is not. Message-classified at the classify seam, path-scoped to /data/eam/ so generic 403s elsewhere cannot shift (the trial_not_expired pattern, classify edition). Exit 6 — target state.

Fields

§endpoint: Option<String>

URL of the refused request, when known.

§

ProviderRootUnsupported

A provider-ROOT tag path ([default] alone, or a bare first segment that resolves to a provider) met the tagConfig route — system.tag.getConfiguration/exportTags need an RPC context WebDev threads don’t carry (live-proven 8.3.3 b2026012009, both gateways; 07-UAT test 12). The route refuses honestly (pre-call bracket detection + RpcContext translation for the bare form) instead of surfacing the IllegalStateException as a generic route error; subtree paths ([default]folder) are the supported form. Exit 6 — target state: a platform limitation, not a bug.

Fields

§endpoint: Option<String>

URL of the tagConfig route request, when known.

§

EamTaskTypeRefused

An eam task new whose type is in the REFUSED set — eam_restoreBackup, eam_installModules, eam_remoteUpgrade are fleet-destructive (they push backups/modules/upgrades to every AGENT target), and the CLI refuses them outright over guard-everything: honest refusal with the v2 scope pointer (the planner-locked create ladder’s top rung). Exit 6 — target state (additive slug alongside Task 2’s).

Fields

§task_type: String

The refused profile.type token.

§

EamTaskInFlight

An eam task force whose slot a leftover run occupies — the force route answers 409 with the gateway’s own Jetty page (“Task ‘X (forced)’ already exists! It must be completed or deleted before another task of this type can be force executed.”; live-captured 8.3.3, 07-UAT test 7). Exit 6 — target state (the session_not_prunable precedent, force-route edition): the gateway’s state refused the command, not a bug; classify()’s path-scoped 409 arm constructs this.

Fields

§task: String

The forced task’s name (the force URL’s last segment).

§detail: String

The gateway’s Jetty page message verbatim when sniffed; the ‘(forced)’ fallback text otherwise.

§endpoint: Option<String>

URL of the refused force POST, when known.

§

ScriptExecNotConfigured

The scriptExec route is not configured for this profile — no webdev secret is persisted, which can only mean ign webdev deploy --with-script-exec has never run (deploy persists the secret 0600 BEFORE upload, so a deployed route without a stored secret is not a reachable state). ign script run’s opt-in is STRUCTURAL — the deploy flag — so the verb carries no --yes guard and refuses here instead (07-03, SCRPT-01: the TrialNotExpired precedent — action-constructed, not classify). Exit 6 — target state.

Fields

§profile: String

The profile whose secret store is empty.

§

LintToolAbsent

ign lint found no ignition-lint executable on PATH — the delegation has nothing to delegate to (07-04, INTR-02). The hint carries the install command + repo. Exit 6 — target state (additive slug; the environment lacks the tool, the command is fine).

§

NodeToolAbsent

ign e2e init found no node executable on PATH — the scaffold it would write is unusable without one (QUICK-tg4).

Exit 6, mirroring Self::LintToolAbsent line for line: this is the SAME shape — a local external tool a verb delegates to is absent, with an install hint. It deliberately does NOT join exit 7, whose sole slug is rig_error for docker/compose rig failures; putting a missing Node there would force a relabel of a locked exit class.

Fields

§tool: String

The tool that was looked for (node).

§

GatewayClientError

The gateway answered the api call with a 4xx this CLI does not curate — the caller’s request is the problem, and the body is theirs to read. Exit 2 (usage class; additive slug — the poll_interval_too_small precedent: same class, own slug, no new exit code). Constructed ONLY by the api-call-scoped classify arm (09-01: the api_call parameter) — a curated command’s 4xx keeps its existing classification (the catch-all cannot fire without the parameter). The body is the gateway’s answer VERBATIM, truncated at GATEWAY_CLIENT_BODY_CAP_BYTES with the explicit GATEWAY_CLIENT_BODY_TRUNCATION_MARKER via truncate_api_body at construction.

Fields

§status: u16

HTTP status the gateway answered with.

§endpoint: String

Full URL of the rejected request.

§body: String

The response body VERBATIM, truncated at GATEWAY_CLIENT_BODY_CAP_BYTES with an explicit marker.

§

BundleNotAvailable

No diagnostics bundle is available — the status poll ANSWERED with a captured TERMINAL steady state meaning “no current bundle” (Invalid: live-proven on 8.3.6 rig ign-p9-836, 2026-09-07 UAT / 09-UAT.md Gap 3 — a Valid bundle decays to Invalid within ~2 minutes UNPROMPTED and stays Invalid; only a fresh generate changes it, polling cannot). Exit 6 — target state (the ImportDenied precedent: a gateway-answered refusal riding its own class, action-constructed by bundle wait’s probe, not classify).

Fields

§state: String

The observed steady state (the captured unavailable vocabulary, e.g. Invalid).

§

ModuleFeedUnreachable

Transport failure reaching a third-party module release feed or its asset CDN — DNS/connect/timeout/TLS (Phase 15, D-06). Exit 4: same network class as Self::Network, but a SEPARATE slug and wording — Network’s Display hard-codes “gateway unreachable”, which is actively wrong here (api.github.com is not a gateway, and the user’s own gateway may be perfectly reachable). This is the offline signal fetch_and_verify returns when the cache is empty (SC-4’s negative half).

Fields

§url: String

The feed or CDN URL that could not be reached.

§source: Option<Error>
§

ModuleReleaseNotFound

No release exists for the pinned tag, or the release carries no asset of the expected name (Phase 15, SC-1’s “unknown version” refusal). Exit 6 — target state: names BOTH the requested version and the resolved URL, and (for a missing asset) both the expected asset name and the names actually present, so the caller never has to guess which lookup failed or falls back to “latest”.

Fields

§module: String

The crate::module::ModuleSpec::id being fetched.

§version: String

The requested version string.

§url: String

The tag-pinned releases URL that was queried.

§detail: String

What specifically was missing (no release for the tag, or no matching asset — names the asset actually present).

§

ModuleDigestMismatch(Box<ModuleDigestMismatchDetails>)

Downloaded bytes hash to something other than the release’s published digest — SC-2’s hard refusal (Phase 15; this variant is defined in 15-01, the branch is exercised starting 15-02). Exit 6 — target state: the feed answered and served bytes, but what it served cannot be trusted. The bytes are discarded (never persisted to the cache) and BOTH digests are named.

Payload is BOXED: five inline Strings put CoreError at exactly clippy’s 128-byte result_large_err threshold, which fails -D warnings in every crate returning Result<_, CoreError> — ignition-tui first. Error paths are cold, so one allocation on construction is the cheap side of that trade.

§

ModuleFeedUnusable

The module release feed ANSWERED but not usably — rate-limited, unauthenticated 401/403, 5xx, an unparseable body, an asset with no published digest, or an insecure downgrade of the asset URL (Phase 15). Exit 6 — target state: distinct from Self::ModuleFeedUnreachable (exit 4 — transport never reached the feed at all); here the feed DID answer, just not with something ign can safely act on.

Fields

§url: String

The feed or asset URL that answered unusably.

§detail: String

What specifically made the answer unusable.

§

ModuleDigestChanged(Box<ModuleDigestChangedDetails>)

A pinned version’s upstream digest differs from what’s already cached — D-02’s default refusal on FetchPolicy::Refresh / AcceptUpstreamChange (Phase 15, 15-02): the feed answered fine, but what it currently publishes for this version no longer matches what was verified and cached before. Exit 6 — target state: names BOTH full digests and the path of the cached artifact, which is left on disk UNTOUCHED (no path in module/ deletes, truncates, or overwrites a cache entry). FetchPolicy::AcceptUpstreamChange is the explicit, documented override.

Payload is BOXED for the same reason as Self::ModuleDigestMismatch — see that variant.

§

ModuleNotRegistered

A declared module id has no matching registry entry (Phase 16, D-13). A well-formed id that simply isn’t registered is a CONFIG problem, not malformed input (exit 2 belongs to validate_module_id/validate_version) and not a Docker failure (exit 7 is Self::Rig) — every OTHER module provisioning refusal (missing artifact, non-file artifact, relative path, underivable service) stays CoreError::Rig. Exit 3, structurally the Self::ProfileNotFound shape: names both the bad id and every id that IS registered.

Fields

§id: String

The declared id with no matching crate::module::ModuleSpec.

§known: Vec<String>

Every currently registered crate::module::ModuleSpec::id.

§

ModuleUninstallDenied

The gateway ANSWERED DELETE /data/api/v1/modules/uninstall with HTTP 200 but the body says {"success": false, "failedUninstalls": {"uninstall": […]}} — the denial-rides-200 class (Self::ImportDenied’s precedent) applied to module uninstall (Phase 19, D-19-03): live-verified that a stock module, a bogus id, and a still-mounted module ALL answer 200 with success:false. An unparseable body, a missing success, or an absent failedUninstalls all map here too — absence of detail must never degrade into a reported success. Exit 6 — target state: names both the registry id and the gateway id that was sent, plus every failed id the gateway reported (or the sent id itself when the gateway gave no detail).

Fields

§module_id: String

The registry slug (git) the caller named.

§gateway_module_id: String

The gateway’s own id (crate::module::ModuleSpec::gateway_module_id) sent in the request.

§failed: Vec<String>

failedUninstalls.uninstall verbatim, or [gateway_module_id] when the gateway’s body carried no usable detail.

§endpoint: Option<String>

URL of the refused DELETE, when known.

§

ScanLockHeld

Another actor holds the gateway’s scan-lock. Exit 6 — target state. Constructed by the route-scoped scan-lock arm in classify.rs (20-03); kind is config or projects. actor is the holder’s opaque identity string when the gateway named it (api-token:<name>:<ip>), echoed and never parsed; None when the refusal did not name one.

Fields

§actor: Option<String>

The holder’s identity string, when the gateway named it.

§kind: String

Which scan-lock: config or projects.

§endpoint: Option<String>

URL of the refused request, when known.

§

ResourceSignatureRejected

The gateway refused a resource write over its signature. Exit 6 — target state. Constructed ONLY by the deploy-scoped write helper in client/deploy_api.rs (20-04), never by classify.rs, so the v1.1 EAM 500 pin stays exit 1 internal. The payload deliberately carries no signature and no gateway problem text: 8.3.3 problem messages leak the live signature.

Fields

§name: String

The resource name that was being written.

§reason: SignatureReason

Why the signature was refused.

§endpoint: Option<String>

URL of the refused request, when known.

§

ResourceExists

A resource create named a resource that already exists. Exit 6 — target state. Constructed ONLY by the deploy-scoped create helper in client/deploy_api.rs from the live 409 JSON problem body (20-LIVE-CAPTURES D10), never by classify.rs. The payload carries no gateway problem text or stacktrace.

Fields

§name: String

The resource name that was being created.

§endpoint: Option<String>

URL of the refused request, when known.

§

ModeExists

A deployment-mode create named a mode that is already defined. Exit 6 — target state. Constructed ONLY by the deploy-scoped mode create in client/deploy_api.rs from the live 409 (D6).

Fields

§name: String

The mode name that was being created.

§endpoint: Option<String>

URL of the refused request, when known.

§

DeployTreeInvalid(Box<DeployTreeInvalidDetails>)

A declared gateway tree failed render validation (21-03): one or more findings, each naming its file and, for YAML syntax and schema defects, a line and column. Exit 2 — usage class: the CALLER authored the tree and must fix it. Render is offline, so there is no endpoint. Boxed to keep CoreError under clippy’s result_large_err threshold.

§

EmbeddedSecret(Box<EmbeddedSecretDetails>)

A declared tree carries an Embedded or plaintext secret (21-03). Exit 2 — usage class. The payload holds JSON paths and other findings only: no field exists that could carry a secret value.

§

TransportFailed

A deploy host transport could not read (or later write) a node’s gateway data directory (22-01): a missing or unreadable directory, a hostile live tree (symlink, special file, non-UTF-8 name), a size cap breach or an ssh failure. Exit 4 — network class: the host could not be reached or read. A failed read is NEVER an empty result, so a plan cannot mistake an unreadable tree for deletions. detail names paths and causes only, never file content.

Fields

§operation: String

What was being done, e.g. read.

§node: String

The target node label, e.g. nodes.master.

§detail: String

What went wrong; names paths and causes, never file content.

§

DeployLedgerInvalid

The on-box declared-names ledger exists but cannot be trusted (22-03, D-07): unreadable, empty, over its size cap, not strict UTF-8 JSON, of another schema version, naming another gateway or mode, unsorted or duplicated, or listing a path plan must never delete. Exit 6 - target_state class: the on-box state is wrong, not the caller’s input. Plan never falls back to an empty delete set. problem names fields and listed paths only, never other file content.

Fields

§location: String

The ledger location relative to the node’s data directory.

§problem: String

What is wrong; names fields and listed paths, never file content.

§

PlanStale

The plan the caller reviewed is no longer the plan (23-02, DAPL-02): --plan-sha256 differs from the recomputed plan_sha256, or the on-box pre-image changed under the scan lock. Exit 6 - target_state class: the gateway moved since the review. Carries hashes only.

Fields

§expected: String

The plan_sha256 the caller reviewed.

§actual: String

The plan_sha256 of the plan as it is now.

§detail: String

Where the mismatch was found, e.g. review hash; no file content.

§

DestructiveChangeRefused

A destructive or drifted plan was applied without its flag (23-02, DAPL-02). Exit 2 - usage class: the caller must pass --allow-destructive or --allow-drift <reason>. Carries unit keys and counts only.

Fields

§gate: String

Which gate refused: destructive or drift.

§keys: Vec<String>

The first APPLY_LIST_SHOWN offending unit keys, byte-sorted.

§count: usize

How many entries the gate refused in all.

§

DeployBlocked

A removal that cannot take effect (23-02, DAPL-01): the unit’s core copy shadows the mode collection, so deleting from the mode collection changes nothing. No flag permits it. Exit 6.

Fields

§keys: Vec<String>

The shadows_removal unit keys, byte-sorted.

§

DeployPreflightFailed

One or more apply preflight checks failed (23-02, DAPL-04). Exit 6. Nothing was written to the gateway. The payload is BOXED so the large list stays off every Result<_, CoreError>.

Fields

§failures: Box<[PreflightFailure]>

Every failed check, in the order the checks ran.

§

DeployJournalPresent

An interrupted deploy left its journal on the box (23-02, D-09). Exit 6. The message, not the hint, carries the recovery command.

Fields

§run_id: String

The interrupted run.

§env: String

The --env value the recovery command needs.

§location: String

The on-box journal location.

§

DeployLiveChanged

Live files changed after the run wrote them, so a rollback would overwrite someone’s edit (23-02, DAPL-07). Exit 6. Carries paths and counts only.

Fields

§run_id: String

The run being rolled back.

§paths: Vec<String>

The first APPLY_LIST_SHOWN changed paths, byte-sorted.

§count: usize

How many touched paths changed in all.

§

DeployRunInvalid

A run’s record or snapshot cannot be trusted (23-02, D-04). Exit 6. problem names fields and paths only, never file content.

Fields

§run_id: String

The run id asked for.

§problem: String

What is wrong.

§

RollbackFailed(Box<RollbackFailure>)

A rollback could not restore the pre-apply files (23-02, D-12). Exit 6. Boxed to keep CoreError under clippy’s result_large_err.

§

ProjectGitManaged

deploy projects refused a project the git module still manages (25-07, DPRJ-04, D-11): the project’s .git entry exists on the gateway host. Exit 6 - target_state class: the gateway is not in a state this deploy may touch. The tool never deletes a .git; an administrator removes it per project. Carries the project name, the location below the data directory and the kind (directory, file, symlink, other) only.

Fields

§project: String

The gateway project name.

§location: String

The .git path below the node’s data directory.

§kind: String

What the entry is.

§

ProjectParentInvalid

deploy projects refused a project whose parent cannot be used (25-10, DPRJ-02, D-05, K6): the parent named in the repo’s project.json is missing on the gateway, closes a cycle, or is not inheritable. Exit 6 - target_state class: the gateway is not in a state this deploy may build on. Carries names and the reason word (missing, cycle, not_inheritable) only. The parent is only read.

Fields

§project: String

The gateway project being deployed.

§parent: String

The parent named in the repo’s project.json.

§reason: String

missing, cycle or not_inheritable.

§

ProjectHashMismatch

deploy projects refused an artifact that is not the one that was reviewed (25-11, SC-1, D-01, V1): --artifact-sha256 differs from the canonical digest of the artifact the checkout builds. Exit 6 - target_state class: the checkout is not in the state the reviewer saw. The comparison runs after the local build and before any host or gateway contact, so nothing was uploaded. Carries the project name and the two hashes only.

Fields

§project: String

The gateway project name.

§expected: String

The --artifact-sha256 the caller reviewed.

§actual: String

The canonical digest of the artifact this checkout builds.

Implementations§

Source§

impl CoreError

Source

pub const DEPLOY_SLUGS: &'static [&'static str]

The deploy slugs (21-03), in the order the README row lists them.

Source

pub fn code(&self) -> &'static str

Stable machine slug — public contract, never respell.

Source

pub fn exit_code(&self) -> u8

The LOCKED exit-code mapping — the only place exit codes are decided.

Source

pub fn hint(&self) -> Option<String>

Actionable next step (CORE-05). Every class carries one.

Source

pub fn endpoint(&self) -> Option<String>

URL/path of the request involved, when one was — populated for the network, auth, and target-state classes (CORE-05).

Source

pub fn deploy_tree_invalid( file: impl Into<String>, line: Option<usize>, column: Option<usize>, message: impl Into<String>, ) -> Self

A single positioned (or file-only, when line/column are None) tree finding as a Self::DeployTreeInvalid.

Source

pub fn deploy_findings(findings: Vec<DeployFinding>) -> Self

Several tree findings as one Self::DeployTreeInvalid. An empty vector is a programming error: debug builds assert, release builds still return one generic finding so the error is never empty.

Source

pub fn embedded_secret( paths: Vec<String>, other_findings: Vec<DeployFinding>, ) -> Self

An embedded or plaintext secret at each of paths (locations only, never values), plus any non-secret findings from the same render.

Source

pub fn tui_tty_refusal() -> Self

The ign tui TTY refusal (06-07): InvalidInput carrying the ONE reason whose hint is terminal-contextual — see TUI_TTY_REFUSAL_REASON. Same slug, same exit 2 (frozen taxonomy; only the hint differs).

Source

pub fn top_tty_refusal() -> Self

The ign top TTY refusal (itop): the tui refusal’s sibling at one command over — same slug, same exit 2, the hint naming the monitor’s command. See TOP_TTY_REFUSAL_REASON.

Source

pub fn envelope<'a>(&self, profile: Option<&'a str>) -> ErrorEnvelope<'a>

Build the LOCKED failure envelope for this error (field order is part of the golden contract: ok, profile, error then code, message, endpoint, hint).

Trait Implementations§

Source§

impl Debug for CoreError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for CoreError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for CoreError

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0:

use the Display impl or to_string()

1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more