pub enum RunError {
Show 31 variants
Stalled {
node: String,
},
UnboundedCycle {
nodes: Vec<String>,
},
Unreachable {
nodes: Vec<String>,
},
UnresolvedRef {
what: String,
},
InvalidCondition {
edge: String,
why: String,
},
NoToolLlm {
node: String,
},
BudgetExhausted {
axis: BudgetAxis,
},
DanglingIntent {
key: String,
},
ReplayDivergence {
what: String,
},
ManifestMismatch {
why: String,
},
UnknownAsk {
tool_call_id: String,
},
Unauthorized {
what: String,
},
Canceled {
by: String,
reason: String,
},
ReducerLawViolation {
key: String,
},
CheckpointTooLarge {
bytes: usize,
cap: usize,
},
Tainted {
why: String,
},
RetentionRefused {
why: String,
},
CodeExecRefused {
condition: String,
},
InvalidPlan {
why: String,
},
Storage {
detail: String,
},
LeaseLost {
run_id: String,
},
EgressRefused {
destination: String,
},
AnonReplayUnsafe {
ns: String,
scope: String,
},
ContextExceeded {
node: String,
tokens: u64,
ceiling: Option<u64>,
},
ModelMismatch {
pinned: String,
offered: String,
},
EngineMismatch {
written_by: String,
epoch: u32,
this_epoch: u32,
},
ConcurrencyLimit {
scope: String,
limit: u32,
},
TransferLimitInvalid {
node: String,
detail: String,
},
NotPausable {
run_id: String,
why: String,
},
NoDecider {
node: String,
},
SavedQueryUnavailable {
node: String,
name: String,
why: String,
},
}Expand description
A runtime failure with a stable RUN-Ennn code.
Variants§
Stalled
RUN-E001 — the run drained with no terminal node reaching success; names the decision node whose conditions all evaluated false.
UnboundedCycle
RUN-E002 — an unbounded cycle: a strongly-connected component with no
max_cycles edge.
Unreachable
RUN-E003 — node(s) unreachable from the entry.
UnresolvedRef
RUN-E004 — a binding or pinned hash does not resolve (or a journal ref is absent without an erasure receipt).
InvalidCondition
RUN-E005 — a condition failed validation at load.
NoToolLlm
RUN-E006 — an abstract node with no tool-calling LLM configured.
BudgetExhausted
RUN-E007 — a budget axis is exhausted.
Fields
axis: BudgetAxisDanglingIntent
RUN-E008 — a dangling intent on resume with on_dangling = fail.
ReplayDivergence
RUN-E009 — replay divergence: a re-derived decision, counter, or checkpoint disagrees with the journal.
ManifestMismatch
RUN-E010 — checkpoint does not match the run manifest.
UnknownAsk
RUN-E011 — a response names no pending Client ask.
RUN-E012 — a run operation the session’s rights do not cover.
Fields
Canceled
RUN-E013 — the run was canceled.
ReducerLawViolation
RUN-E014 — a reducer violated its laws (debug sampling).
CheckpointTooLarge
RUN-E015 — a checkpoint exceeds the size cap after spill.
Tainted
RUN-E016 — the journal is tainted: forked supersession tips, or a
resume of a copied file without --fork / the owner nonce.
RetentionRefused
RUN-E017 — a retention floor or legal hold refuses a destruction.
CodeExecRefused
RUN-E018 — code execution refused; names the failed gate condition.
InvalidPlan
RUN-E019 — the workflow failed structural validation (V1/V2 shape errors that are not one of the specific codes above).
Storage
RUN-E020 — a store operation failed under the runtime (wraps the
underlying DOMAIN-Ennn message, which stays in the detail).
LeaseLost
RUN-E021 — the run lease was lost mid-flight: another driver took this run over while we were advancing it.
Before this existed, two drivers advancing one run last-write-wins in
the journal — silently. The doc comment on Tainted claimed forked tips
were detected; they were not. Refusing here fails safe by prevention
rather than by after-the-fact detection.
Note the code: the design proposal called this RUN-E017, but that is
RetentionRefused and codes are append-only.
EgressRefused
RUN-E022 — a host command’s outbound call was refused: a destination
outside the run’s allowlist, a method its grant does not permit, a
credential it may not spend, a request header it may not set —
undeclared, or one the broker owns (#105) — or a CAS blob read without
the blob capability (#106). One code for “the broker said no”,
whichever of its doors was knocked on.
The trigger evaluator reports the same condition as TRG-E009, the way
a storage failure is TRG-E010 there and RUN-E020 here. One
condition, one code per subsystem that reports it.
AnonReplayUnsafe
RUN-E023 — an anonymization policy covers this run’s namespace but
cannot replay, so the model boundary would make verify diverge.
Session scope numbers tokens by order of appearance, so the same input yields different placeholders on a replay. Only value-derived (HMAC) tokens are stable across handles and processes — that is D8 — and the key for them is HKDF-derived from the page key, which is why this also means an encrypted memory.
ContextExceeded
RUN-E024 — an abstract node’s transcript is over llm_context_tokens
and there is nothing left to fold: the node’s input and the kept tail
alone exceed the ceiling, or a fold already ran and did not help.
Deliberately NOT a retry and not a second fold. A fold that cannot find
a foldable middle will never find one by trying again, and looping on it
would spend the effect budget summarizing summaries. The honest answer
is a failed node naming the ceiling it could not fit under — raise it,
bound the tool results (llm_tool_result_chars), or split the node.
ceiling is None when no ceiling was configured and the PROVIDER
refused the transcript — the limit was learned from the rejection
rather than predicted.
ModelMismatch
RUN-E025 — the model configuration this run STARTED under is not the one on offer now (#287).
Raised before the lease is taken and before any grain is written: a
resume that would have finished a parked run on a different model,
provider or region simply does not begin. areev run fork is the
sanctioned way through — a fork writes a new manifest carrying the new
pin and records what it forked from, so the change is a recorded
decision rather than an undocumented drift.
EngineMismatch
RUN-E026 — this run was written by a scheduler generation whose decisions differ from this build’s (#288).
A patch upgrade must not strand parked approval runs, so the VERSION string is not what is compared — only the scheduler epoch, which moves exactly when a change makes an existing journal replay differently.
ConcurrencyLimit
RUN-E027 — starting this run would exceed a concurrency cap (#296).
RETRYABLE by nature: the cap is a backstop beneath the host’s own dispatcher, not a verdict on the run. Nothing is written under the run id, so the same id starts once a slot frees, and a trigger firing refused here leaves its item unconsumed (the #129 rule for RUN-E018).
TransferLimitInvalid
RUN-E028 — a Tool declares a brokered-transfer ceiling
(runtime_limits.max_response_bytes / max_request_bytes) that is
malformed, zero, or above the 32 MiB hard maximum (#339).
Refused at run start — before any upstream I/O — and never clamped: a tool that declared more than the host will carry would otherwise fail on the first document between the two sizes, with nothing pointing at its own declaration.
NotPausable
RUN-E029 — a pause was asked of a run that cannot be paused (#344): it already finished (completed, failed, stalled, canceled, or out of budget), or a cancel is pending against it — cancel wins over pause.
Pausing an already-paused (or already-pause-requested) run is NOT this error; it is idempotent and answers with the standing request.
NoDecider
RUN-E030 — a plan binds a decision node (a Tool Definition whose
executor_uri is areev://decide) and this host has no decision
backend installed.
Refused at run start (the V7 freeze) and on resume — before the lease and before any grain is written — naming the node, so a run never starts down a path whose branch point cannot be answered here. The scheduler’s OPTIONAL asks (the decision-guided fold, the tool-offer narrowing) never raise this: without a backend they are not asked.
RUN-E031 — a declared op: query read (#370) cannot be served: at
run start the saved query is not defined or its parameters do not fit
the declaration; at dispatch the body pinned at run start is missing
from the manifest or no longer matches the hash recorded beside it.
The run reads the body PINNED at start, never the live qry: row, so
a body superseded or dropped mid-run does not change a running run;
this code is what a pin that cannot be honoured fails with instead of
quietly reading something else.
Implementations§
Trait Implementations§
Source§impl Error for RunError
impl Error for RunError
1.30.0 · 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()