Skip to content

Error recovery mid-loop#

How the kernel reacts to a failure surfacing mid-turn — a model-provider error, or a tool-provider (plugin) crash. Both are loop-level behavior and belong here rather than in the category protocol that defines the error taxonomy itself.

Model-provider errors#

Per model/conformance.md#error-taxonomy, the kernel's reaction to each error category is:

  • rate_limited / overloaded: the kernel MUST retry with exponential backoff and jitter. Base retry delays vary by more than an order of magnitude across surveyed harnesses, with no convergent "correct" value — the kernel MUST make the base delay and backoff factor configurable, shipping with canonical defaults rather than requiring configuration before first use: base_delay_ms = 500, backoff_factor = 2, max_retries = 5 (configuration/blocks-reference.md's settings{} block). These are a reasonable midpoint of the observed range across harnesses, not derived from any single one — operator-overridable, not load-bearing precision. The kernel MUST honor a supplied retry_after_seconds when present (both ModelError.retry_after_seconds and, where the transport surfaces raw HTTP headers, retry-after/retry-after-ms forms). Per-attempt and per-session retry caps MUST be tracked separately — a session-wide retry ceiling prevents an endlessly-retrying single call from silently consuming the entire wall-clock/cost budget (turn-algorithm.md#independent-bound-dimensions) without ever advancing the turn counter.
  • context_length_exceeded: the kernel MUST NOT blindly retry the same request. This MUST instead trigger a context-reduction path on the next context-assemble pass (compaction/pruning mechanics are context- and memory-provider concerns — see context/README.md and memory/README.md, not specified here) or, if no context provider can shrink further, fail the turn cleanly with a distinguishable status rather than looping.
  • auth_error / invalid_request: the kernel MUST NOT retry and MUST NOT silently fall back to another model in a routing chain — both are configuration/programming errors that retrying cannot fix and that fallback would only mask.
  • content_filtered: the kernel MUST surface this distinctly (already required by model/conformance.md#error-taxonomy) so a post-model-response observer or the frontend can react differently than to a generic failure.

Tool-provider (plugin) crashes#

Denial surfaces as tool-result text in every surveyed open-source harness, letting the model observe and adapt rather than the session dying — this generalizes cleanly to plugin crashes even though the two failure modes aren't identical. A single Invoke failure SHOULD be surfaced as an error-flagged tool_result content block for that call (not a session-ending fault), giving the model the same observe-and-adapt opportunity a denial gets. Repeated crashes from the same provider within a session SHOULD trip the same circuit-breaker mechanism described for denials in plan-apply-gate.md#circuit-breaker-on-repeated-denials, since an infinite crash-retry loop is the failure-mode analog of a denial storm. This is a design recommendation reasoned by analogy from the denial pattern rather than a pattern directly established for crashes specifically — see conformance.md#open-questions.

A crashed plugin subprocess surfaces as the process_crashed error category — the kernel does not treat a crashed plugin as a silent hang; it fails the in-flight call promptly, which is what makes the SHOULD-level tool-result-error handling above possible in the first place.