Skip to main content

ErrorCode

Enum ErrorCode 

Source
pub enum ErrorCode {
Show 43 variants UserCancelled, ExecutionTimeout, CheckpointTimeout, ProviderRateLimit, ProviderAuth, ProviderTokenLimit, ProviderServer, ProviderServer500, ProviderBadGateway502, ProviderServiceUnavailable503, ProviderGatewayTimeout504, ProviderNetwork, ProviderParse, ProviderOther, InternalPanic, InternalDroppedChannel, InternalDeadlock, InternalTaskAborted, InternalOther, ScriptError, ScriptDepthExceeded, PartialRetryExhausted, AuthorRaise, ToolBudgetExceeded, ToolApprovalProtocol, ToolNoRegistry, ToolError, AgentToolsDoubleDispatch, ConfigMissing, LoopOutputBudgetExceeded, LoopMultiCheckpoint, ContextOverflow, ContextNativeUnsupported, ContextCompactionExhausted, CompactionThresholdInvalid, CompactorSignature, CompactionLoopOnly, StdFormatMissing, StdFormatSyntax, StdJsonParse, StdJsonStringify, StdRegexInvalid, Other,
}
Expand description

Stable, fine-grained error identifier. Each code maps to exactly one ErrorKind and carries a default user-facing message. Wire form: AKRIBES-E-<UPPER-KEBAB> (e.g. AKRIBES-E-PROVIDER-RATE-LIMIT).

Codes are intentionally durable: once published, the wire string and kind() mapping should not change. Add new variants for new conditions rather than repurposing old ones; SDKs match on these strings to drive retry/UI/triage logic.

Variants§

§

UserCancelled

Explicit user/client cancellation via POST /executions/:id/cancel.

§

ExecutionTimeout

Server-side execution-budget timeout (AKRIBES_EXECUTION_TIMEOUT).

§

CheckpointTimeout

on_timeout window on a checkpoint elapsed without a resume.

§

ProviderRateLimit

Provider returned a 429 / rate-limit / quota-exhausted response.

§

ProviderAuth

Provider returned 401/403, or an API key was missing / not configured.

§

ProviderTokenLimit

Provider’s reported context window or max_tokens was exceeded.

§

ProviderServer

Legacy umbrella for any 5xx — kept for wire backward-compat after the issue #1296 split. New code should construct one of [ProviderServer500], [ProviderBadGateway502], [ProviderServiceUnavailable503], or [ProviderGatewayTimeout504]. Decoding the old AKRIBES-E-PROVIDER-SERVER wire string yields this variant so SDKs that match on it stay green.

§

ProviderServer500

Provider returned HTTP 500. Maybe-transient; short retry-with-backoff.

§

ProviderBadGateway502

Provider returned HTTP 502 (bad gateway). Retry with short backoff.

§

ProviderServiceUnavailable503

Provider returned HTTP 503 (service unavailable). Rate-limit-adjacent — honour Retry-After aggressively.

§

ProviderGatewayTimeout504

Provider returned HTTP 504 (gateway timeout). Longer base backoff since the slow side is unlikely to recover faster than the request.

§

ProviderNetwork

Network-level failure reaching the provider (DNS, TLS, reset, per-provider request timeout).

§

ProviderParse

Provider response did not parse as the expected schema.

§

ProviderOther

Generic provider/runtime failure that didn’t fit a more specific bucket.

§

InternalPanic

A spawned engine task panicked (host-side bug).

§

InternalDroppedChannel

A oneshot::Receiver returned Err because its sender was dropped before sending — covers breakpoint resume, checkpoint resume, tool-approval resume. Indicates a server-side cleanup race or a host bug, never a user action.

§

InternalDeadlock

Engine reached a state with pending nodes but none ready to run — dependency cycle or compiler bug.

§

InternalTaskAborted

JoinError that wasn’t a panic and wasn’t a recognized cancel — tokio runtime aborted the task externally. Treated as a host invariant violation.

§

InternalOther

Generic “this should not happen” host failure that doesn’t fit the more specific Internal* codes.

§

ScriptError

Generic workflow-author error not categorised more specifically.

§

ScriptDepthExceeded

Cross-script call(...) chain exceeded the depth cap.

§

PartialRetryExhausted

Validation retries exhausted with allow_partial: true (issue #202) — partial-retry sentinel routed to on unable / handler.

§

AuthorRaise

Workflow author’s fail arm fired — the LLM returned an Unable or other non-success variant the author mapped to failure.

§

ToolBudgetExceeded

Per-agent tool budget (tool_budget) exceeded.

§

ToolApprovalProtocol

Tool approval resume returned a payload that wasn’t the expected { approve: bool, args?: Value } shape — host protocol violation.

§

ToolNoRegistry

Tool call attempted but no MCP registry was attached (script-only engine, missing host wiring).

§

ToolError

MCP tool call returned a tool-side failure (the registry exists and dispatched, but the tool itself errored).

§

AgentToolsDoubleDispatch

Agent dispatched a second tool_use after the engine had already folded one round-trip’s tool results back into the conversation. Agents are single-round-trip by design — multi-turn agentic behaviour belongs on a loop block. Surfaces when an LLM ignores the synthesized “produce your final answer now” follow-up turn and tries to invoke tools again. The fix is either to use a loop block or to tighten the agent’s system prompt.

§

ConfigMissing

Required configuration missing (API key, env var, etc.).

§

LoopOutputBudgetExceeded

Loop block exceeded its max_total_output_tokens budget. The loop driver accumulates each turn’s output_tokens from the provider and stamps this code on the resulting LoopEnd { value: FatalError } once the running total exceeds the per-loop or project-default cap.

§

LoopMultiCheckpoint

A second checkpoint fired in the same loop turn. The supported envelope is at most one checkpoint per turn — the driver tracks a per-turn counter and fails fast when the increment goes past 1. Surfacing this as a distinct code (rather than Other) lets SDKs and the Studio render a targeted explanation: split the checkpoints across turns, or move one onto a non-loop sibling.

§

ContextOverflow

Mode 1 (compaction: none / omitted) only — the assembled request would exceed the model’s context window. Pre-call diagnostic emitted by Engine::run_compaction_chain; replaces the cryptic provider 400 from upstream. Carries the conversation length, the model cap, and the agent in the message body.

§

ContextNativeUnsupported

compaction: native() (or at <T>: native()) used with a model whose ModelEntry::native_compaction_capable is false. The related-info span points at the model declaration.

§

ContextCompactionExhausted

All custom-chain steps ran and the conversation still exceeds the configured cap. Surfaces with the chain of attempted strategies in the message body. Emitted instead of a provider 400 — fail-fast at the akribes seam.

§

CompactionThresholdInvalid

compaction: at <invalid> — value <= 0, percent > 100, or duplicate threshold in a custom chain. Compile-time only.

§

CompactorSignature

User-defined compactor task referenced from a compaction step doesn’t match one of the four supported signatures (str|list[message] -> str|list[message]). Compile-time only.

§

CompactionLoopOnly

compact_to_state(field=...) used outside a loop’s compaction: block. The primitive is loop-only because it writes into the loop’s state record. Compile-time only.

§

StdFormatMissing

std.format placeholder {name} not present in args. Stable string form: AKRIBES-E-STD-FORMAT-MISS-001 (#1224).

§

StdFormatSyntax

std.format malformed template (unclosed {, empty {}, stray }). Stable string form: AKRIBES-E-STD-FORMAT-SYNTAX-001.

§

StdJsonParse

std.json_parse could not parse the input string as JSON. Stable string form: AKRIBES-E-STD-JSON-PARSE-001.

§

StdJsonStringify

std.json_stringify could not serialise the input value (e.g. FatalError payload; non-serializable). Stable string form: AKRIBES-E-STD-JSON-STRINGIFY-001.

§

StdRegexInvalid

std.regex_extract was given an invalid regex pattern. Stable string form: AKRIBES-E-STD-REGEX-001.

§

Other

Catch-all for sites that haven’t been migrated to a richer code. Prefer adding a specific variant — this is for transition only.

Implementations§

Source§

impl ErrorCode

Source

pub fn parse_retry_after_ms(msg: &str) -> Option<u64>

Extract a retry_after_ms hint from a provider error message when the wire response carried one (provider implementations usually echo it as retry-after: <secs> or similar). None when no such hint is present.

Honours both RFC 9110 §10.2.3 forms:

  1. delta-secondsRetry-After: 30 (returned as 30_000).
  2. HTTP-dateRetry-After: Wed, 21 Oct 2026 07:28:00 GMT parsed via httpdate::parse_http_date and returned as the delta from SystemTime::now(), clamped to >= 0.
Source§

impl ErrorCode

Source

pub fn kind(&self) -> ErrorKind

The ErrorKind bucket this code belongs to. Computed once, statically — used by consumers that want the rollup behaviour (is_transient, suggested_action) without hand-mapping codes.

Source

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

Stable wire identifier (AKRIBES-E-<UPPER-KEBAB>). This is the string consumers should match on for retry/UI logic.

Source

pub fn from_wire(s: &str) -> Option<Self>

Parse the canonical wire form (AKRIBES-E-<UPPER-KEBAB>) back to a code. Returns None for any string we don’t recognise so the caller can decide whether to fall back to ErrorCode::Other or surface the unknown code as-is. Used by the legacy Value::fatal_with_code shim and SDK normalisers.

Source

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

Default user-facing message for this code. Constructors should override only when there is meaningfully more to say to the user (e.g. embedding the offending value), not just to restate the developer message.

Trait Implementations§

Source§

impl Clone for ErrorCode

Source§

fn clone(&self) -> ErrorCode

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ErrorCode

Source§

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

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

impl<'de> Deserialize<'de> for ErrorCode

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Hash for ErrorCode

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for ErrorCode

Source§

fn eq(&self, other: &ErrorCode) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for ErrorCode

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Copy for ErrorCode

Source§

impl Eq for ErrorCode

Source§

impl StructuralPartialEq for ErrorCode

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,