pub enum CoreError {
Show 69 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>,
},
DeployUnreadable {
node: String,
keys: Vec<String>,
},
DeployPairTagsRefused {
mode: String,
keys: Vec<String>,
},
DeployPreflightFailed {
failures: Box<[PreflightFailure]>,
},
DeployJournalPresent {
run_id: String,
env: String,
location: String,
recover_with: Option<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,
hash: &'static str,
expected: String,
actual: String,
},
TagProviderClaimed {
provider: String,
claimed_by: String,
},
TagDeleteNotConfigured {
profile: String,
missing: Vec<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).
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.
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).
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
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).
ProfileNotFound
Named profile absent from config. Exit 3.
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.
No credential resolvable for the profile (env, token_env, keyring all missed or failed). Exit 3.
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).
ConfigInvalid
Config file unreadable or wrong shape. Exit 3.
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).
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
Auth
Gateway reachable but rejected credentials (401/403). Exit 5.
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
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.
GatewayRestarting
Gateway restarting — webserver answers (503) but services are down (verified restart lifecycle: webserver never drops the connection). Exit 6.
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.
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
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
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
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
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.
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
expected: StringThe embedded bundle’s version
(crate::webdev::ROUTE_BUNDLE_VERSION).
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
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
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
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).
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
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.
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.
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).
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
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.
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.
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
body: StringThe 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).
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).
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: StringThe crate::module::ModuleSpec::id being fetched.
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
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: StringThe 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
gateway_module_id: StringThe gateway’s own id (crate::module::ModuleSpec::gateway_module_id)
sent in the request.
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
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
reason: SignatureReasonWhy the signature was refused.
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
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
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
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
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
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: StringWhich gate refused: destructive, drift or provider_wipe
(apply),
downgrade, first_deploy or tag_removal (deploy projects;
tag_removal passes with --allow-destructive since 26-20), or,
with no flag that passes it, provider_emptied (26-07).
keys: Vec<String>The first APPLY_LIST_SHOWN offending unit keys, byte-sorted.
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.
DeployUnreadable
An apply would write, check or delete a unit whose live copy the
host’s sftp server cannot read (quick-261029-ms3): a host path of 240
characters or more, so the live copy is unknown and must never be
taken as absent. Raised when an unreadable unit is declared or listed
in the declared-names ledger, on the master by the plan’s gate, and on
the backup by the backup_read preflight (a unit the apply writes or
deletes that the backup cannot read, WR-02). No flag permits it. Exit
6.
Fields
DeployPairTagsRefused
A deploy to a redundant pair (a target with nodes.backup) would
leave or restore files of a tag-definition or tag-type-definition
unit in the mode collection (debug deploy-tag-redundancy-sync).
Ignition 8.3.6 counts those resources of a mode collection in its
config-resource sync snapshot but leaves them out of every diff, and
syncs tags only from core, so the backup can never match the master
and stops syncing configuration. A pair’s tag units are deployed to
core (quick 261102-cef, A2), so this is only the residue: mode files
of such a unit the apply cannot delete, a manual rollback that
would put mode files back, or a file or folder in such a type folder of
the mode collection that the deploy does not read, an empty folder
included, even beside files the deploy deletes (quick 261103-ell, F3;
quick 261104-7cy, C3). It is removed by hand on the master (README
runbook T6e). No flag permits it. Exit 6.
Fields
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: the file
engine’s ign deploy rollback --run <id> --env <env>, or
recover_with when the journal is another verb’s (26-12: a project
run’s host journal names ign deploy projects --rollback-run).
Fields
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
paths: Vec<String>The first APPLY_LIST_SHOWN changed paths, byte-sorted.
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.
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
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
ProjectHashMismatch
deploy projects refused a checkout 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, or (26-05,
TAGDEP-10) --tags-sha256 differs from the digest of the owned tag
content the checkout holds. Exit 6 - target_state class: the checkout
is not in the state the reviewer saw. The comparison runs offline,
before any host or gateway contact, so nothing was uploaded. Carries
the project name, which hash, and the two hashes only.
Fields
TagProviderClaimed
deploy projects refused a project that lists a tag provider another
source already deploys (26-05, D-05): the gateway-config manifest
gateways/<gateway>/manifest.yaml below the targets root still lists
it in tag_providers. A provider has one owner. Exit 6 - target_state
class. Refused offline, before any host or gateway contact. Carries
names only.
Fields
TagDeleteNotConfigured
A run needs the tagDelete route (26-18, D-13; the 26-17 checkpoint’s
slug: tag_delete_not_configured) but the profile lacks part of its
configuration: the stored route secret webdev_tag_delete_secret,
either env var of the caller pair, or a safe transport (https, or
http to a loopback host; unverified TLS only to a loopback host). Nothing was sent. Exit 6 - target_state
class. Carries names only, never a value.
Implementations§
Source§impl CoreError
impl CoreError
Sourcepub const DEPLOY_SLUGS: &'static [&'static str]
pub const DEPLOY_SLUGS: &'static [&'static str]
The deploy slugs (21-03), in the order the README row lists them.
Sourcepub fn exit_code(&self) -> u8
pub fn exit_code(&self) -> u8
The LOCKED exit-code mapping — the only place exit codes are decided.
Sourcepub fn endpoint(&self) -> Option<String>
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).
Sourcepub fn deploy_tree_invalid(
file: impl Into<String>,
line: Option<usize>,
column: Option<usize>,
message: impl Into<String>,
) -> Self
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.
Sourcepub fn deploy_findings(findings: Vec<DeployFinding>) -> Self
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.
Sourcepub fn embedded_secret(
paths: Vec<String>,
other_findings: Vec<DeployFinding>,
) -> Self
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.
Sourcepub fn tui_tty_refusal() -> Self
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).
Sourcepub fn top_tty_refusal() -> Self
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.
Sourcepub fn envelope<'a>(&self, profile: Option<&'a str>) -> ErrorEnvelope<'a>
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 Error for CoreError
impl Error for CoreError
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()