Skip to content

zidane/errors

The typed errors an agent run can throw, with the helpers that classify and convert provider failures.

import { … } from 'zidane/errors'src/errors-entry.ts

Use zidane/errors to branch on why a run failed without importing the whole package. agent.run() wraps provider failures in these classes, so you match on instanceof instead of parsing provider strings. The entry also holds matchesContextExceeded(), toTypedError(), errorMessage() and OperationTimeoutError. See Errors for retry and budget behavior. AgentLengthResumeExhaustedError and describeProviderLimit() come from the root zidane entry.

TypeScript
import { createAgent } from 'zidane'
import { AgentAbortedError, AgentBudgetExceededError, AgentContextExceededError } from 'zidane/errors'
import { basic } from 'zidane/presets'
import { anthropic } from 'zidane/providers/anthropic'

const agent = createAgent({ ...basic, provider: anthropic(), behavior: { maxCostUsd: 0.5 } })

try {
  await agent.run({ prompt: 'Refactor the largest file in this repo.' })
}
catch (err) {
  if (err instanceof AgentBudgetExceededError)
    console.error(`Hit the ${err.limit} cap at ${err.actualValue}`)
  else if (err instanceof AgentContextExceededError || err instanceof AgentAbortedError)
    console.error(err.message)
  else
    throw err
}

Functions#

errorMessageFunction#

Extract a printable message from an unknown thrown value.

Standardizes the err instanceof Error ? err.message : String(err) idiom that every catch (err) block was reaching for.

TypeScript
function errorMessage(err: unknown): string
Parameters
NameTypeDescription
errunknown

Thrown value of any type.

string

src/errors.ts:775

matchesContextExceededFunction#

Return true when message matches any of the known "context window exceeded" phrasings. Safe for '' / non-strings (returns false).

TypeScript
function matchesContextExceeded(message: unknown): boolean
Parameters
NameTypeDescription
messageunknown

Error message, or any value. Non-string values never match.

boolean

src/errors.ts:446

toTypedErrorFunction#

Convert a ClassifiedError + underlying cause into the matching typed error instance.

TypeScript
function toTypedError(
  classification: ClassifiedError,
  provider: string,
  cause: unknown,
): AgentAbortedError | AgentContextExceededError | AgentProviderError | AgentToolPairingError
Parameters
NameTypeDescription
classificationClassifiedError

Classification returned by the provider.

providerstring

Name of the provider that raised the error.

causeunknown

Original error, attached as the typed error's cause.

src/errors.ts:805

Classes#

AgentAbortedErrorClass#

Thrown when a run is aborted by the consumer via agent.abort() or an external AbortSignal.

TypeScript
class AgentAbortedError extends Error
TypeScript
new AgentAbortedError(message?: string, options?: { cause?: unknown })

Creates the error.

Parameters
NameTypeDefaultDescription
message?string'Agent run aborted'

Error message. Defaults to 'Agent run aborted'.

options?{ cause?: unknown }

Optional cause.

AgentAbortedError properties
NameTypeDescription
codereadonly'aborted'

Stable error code, always 'aborted'.

src/errors.ts:192

AgentAuthErrorClass#

Thrown when a credential cannot be resolved, refreshed or was refused: carries the structured AuthFailure a surface needs to offer "sign in again" for the exact provider and account.

TypeScript
class AgentAuthError extends Error
TypeScript
new AgentAuthError(message: string, auth: AuthFailure, options?: { cause?: unknown })

Creates the error.

Parameters
NameTypeDescription
messagestring

Error message, with guidance.

authAuthFailure

Which sign-in failed and why.

options?{ cause?: unknown }

Optional cause.

AgentAuthError properties
NameTypeDescription
authreadonlyAuthFailure

Which sign-in failed and why.

codereadonly'auth_failed'

Stable error code, always 'auth_failed'.

src/errors.ts:83

AgentBudgetExceededErrorClass#

Thrown by the loop when a run's cumulative cost, token consumption, or wall-clock elapsed time crosses a ceiling configured on AgentBehavior.maxCostUsd / AgentBehavior.maxTotalTokens / AgentBehavior.maxWallMs. Acts as a programmable circuit breaker for unattended runs — without this, the only built-in safety net is AgentBehavior.maxTurns, which doesn't bound a single very expensive turn (large context, deep reasoning).

The breach is checked after each turn completes (post-turn:after), so the run may exceed the budget by one turn's worth of usage before tripping. Callers wanting a tighter pre-turn estimate should layer their own check on top of the usage hook.

The harness treats this the same way as AgentAbortedError: the session run is finalized as 'aborted', persisted stats reflect what was actually consumed, and the parent agent re-throws so a caller's try/catch can branch on err instanceof AgentBudgetExceededError without string-sniffing.

TypeScript
class AgentBudgetExceededError extends Error
TypeScript
new AgentBudgetExceededError(
  options: { actualValue: number; cause?: unknown; limit: 'cost' | 'tokens' | 'wallClock'; limitValue: number },
)

Creates the error.

Parameters
NameTypeDescription
options{ actualValue: number; cause?: unknown; limit: 'cost' | 'tokens' | 'wallClock'; limitValue: number }

The tripped limit, its limitValue, the actualValue at that moment, and an optional cause.

AgentBudgetExceededError properties
NameTypeDescription
actualValuereadonlynumber

Actual consumed value at the moment the cap was crossed (same units as limitValue).

codereadonly'budget_exceeded'

Stable error code, always 'budget_exceeded'.

limitreadonly'cost' | 'tokens' | 'wallClock'

Which ceiling tripped. 'cost' → maxCostUsd, 'tokens' → maxTotalTokens, 'wallClock' → maxWallMs.

limitValuereadonlynumber

The configured cap (USD for cost, total tokens for tokens, ms for wallClock).

src/errors.ts:228

AgentContextExceededErrorClass#

Thrown when the model or provider signals that the context window was exceeded. Downstream consumers should catch this, prune history, and retry.

TypeScript
class AgentContextExceededError extends Error
TypeScript
new AgentContextExceededError(message: string, options: TypedErrorOptions)

Creates the error.

Parameters
NameTypeDescription
messagestring

Error message.

optionsTypedErrorOptions

Provider name (required), plus optional providerCode and cause.

AgentContextExceededError properties
NameTypeDescription
codereadonly'context_exceeded'

Stable error code, always 'context_exceeded'.

providerreadonlystring

Name of the provider that raised the error.

providerCode?readonlystring

Upstream error code, when the provider surfaced one.

src/errors.ts:131

AgentProviderErrorClass#

Thrown when the provider returns a non-context error (auth, rate limit, server error, etc.). Catch-all for unclassified provider failures.

TypeScript
class AgentProviderError extends Error
TypeScript
new AgentProviderError(message: string, options: TypedErrorOptions)

Creates the error.

Parameters
NameTypeDescription
messagestring

Error message.

optionsTypedErrorOptions

Provider name (required), plus optional providerCode, retryable, limit and cause.

AgentProviderError properties
NameTypeDescription
codereadonly'provider_error'

Stable error code, always 'provider_error'.

limit?readonlyProviderLimit

The rate limit, spent quota or overload behind the error, when that is what it was.

providerreadonlystring

Name of the provider that raised the error.

providerCode?readonlystring

Upstream error code, when the provider surfaced one.

retryable?readonlyboolean

Whether a retry with backoff is likely to succeed. See ClassifiedError.retryable. Absent when the provider did not classify the error — callers should treat absent as "don't retry".

src/errors.ts:157

AgentToolNotAllowedErrorClass#

Describes a tool call blocked because the union of allowed-tools across the active skills does not permit it. The gate builds it but never throws it.

Built by the allowed-tools gates registered on tool:gate and mcp:tool:gate. The gate sets block = true and copies this error's message into reason, so consumers that do not look at this typed error still get a useful string.

TypeScript
class AgentToolNotAllowedError extends Error
TypeScript
new AgentToolNotAllowedError(
  options: { activeSkills: readonly string[]; allowedUnion: readonly string[]; cause?: unknown; displayName: string; toolName: string },
)

Creates the error.

Parameters
NameTypeDescription
options{ activeSkills: readonly string[]; allowedUnion: readonly string[]; cause?: unknown; displayName: string; toolName: string }

Tool names, the allowed-tools union, the active skill names, and an optional cause.

AgentToolNotAllowedError properties
NameTypeDescription
activeSkillsreadonlyreadonly string[]

Names of the skills currently active when the block fired.

allowedUnionreadonlyreadonly string[]

Flattened union of allowedTools patterns across active skills.

codereadonly'tool_not_allowed'

Stable error code, always 'tool_not_allowed'.

displayNamereadonlystring

Aliased / wire name the LLM saw.

toolNamereadonlystring

Canonical tool name the agent tried to call.

src/errors.ts:358

AgentToolPairingErrorClass#

Thrown by the pre-send pairing repair when AgentBehavior.strictToolPairing is true and ensureToolResultPairing would otherwise patch over corruption. Strict mode opts into fail-fast for training-data collectors and any consumer that prefers to bail out rather than ship a transcript carrying a SYNTHETIC_TOOL_RESULT_PLACEHOLDER.

The repairs field carries every repair the loop would have made — useful for postmortems and for surfacing exactly which transcripts were rejected.

Note: callers consuming the chat layer (TUI/SDK presets) typically leave strictToolPairing off so user-facing sessions auto-heal instead of crashing.

TypeScript
class AgentToolPairingError extends Error
TypeScript
new AgentToolPairingError(
  options: { cause?: unknown; message: string; provider?: string; providerCode?: string; repairs: readonly { callId?: string; messageIndex: number; mode: string }[] },
)

Creates the error.

Parameters
NameTypeDescription
options{ cause?: unknown; message: string; provider?: string; providerCode?: string; repairs: readonly { callId?: string; messageIndex: number; mode: string }[] }

Message, optional provider and providerCode, the repairs list, and an optional cause.

AgentToolPairingError properties
NameTypeDescription
codereadonly'tool_pairing_corruption'

Stable error code, always 'tool_pairing_corruption'.

provider?readonlystring

Provider whose wire format the corruption would have hit.

providerCode?readonlystring

Upstream error code when the corruption was detected from a 400 response.

repairsreadonlyreadonly { callId?: string; messageIndex: number; mode: string }[]

Repairs the harness would have performed had strict mode been off. Preserves the full diagnostic so consumers can route to telemetry, /rewind flows, or training-data quarantine without re-walking the transcript.

src/errors.ts:310

OperationTimeoutErrorClass#

Error thrown when an operation exceeds its configured time limit.

TypeScript
class OperationTimeoutError extends Error
TypeScript
new OperationTimeoutError(operation: string, timeoutMs: number, message?: string)

Creates an error for an operation that exceeded its time limit.

Parameters
NameTypeDescription
operationstring

Name of the operation that timed out.

timeoutMsnumber

Time limit that was exceeded, in milliseconds.

message?string

Custom message. Defaults to <operation> timed out after <timeoutMs>ms.

OperationTimeoutError properties
NameTypeDescription
codereadonly'operation_timeout'

Stable error code, always 'operation_timeout'.

operationreadonlystring

Name of the operation that timed out.

timeoutMsreadonlynumber

Time limit that was exceeded, in milliseconds.

src/timeout.ts:2

Constants#

CONTEXT_EXCEEDED_MESSAGE_PATTERNSConstant#

Regex patterns matching common "context window exceeded" messages across providers.

Use matchesContextExceeded to test a free-form error message against them. Provider authors can also compose these into their own classifyError fallbacks.

TypeScript
const CONTEXT_EXCEEDED_MESSAGE_PATTERNS: readonly RegExp[]

src/errors.ts:411

Interfaces#

AuthFailureInterface#

Which sign-in failed, enough for a surface to offer fixing it. JSON-safe: it is persisted with the run.

TypeScript
interface AuthFailure
AuthFailure properties
NameTypeDescription
accountId?string

Stable id of the account that failed, when the credential has one.

accountLabel?string

That account's name, when it has one.

holderPid?number

busy: the pid holding the refresh lock, when it is on this host.

kindAuthFailureKind

Why it failed.

providerstring

The provider name as the provider calls itself (anthropic, openai), or the server / integration name.

providerId?string

Credentials key / OAuth flow id (anthropic, openai-codex), when it differs from nothing else; absent for a 401 the loop classified.

source'provider' | 'mcp' | 'integration'

What signs in: a model provider, an MCP server, an integration.

src/errors.ts:61

ClassifiedErrorInterface#

Structured classification returned by Provider.classifyError

TypeScript
interface ClassifiedError
ClassifiedError properties
NameTypeDescription
kindClassifiedErrorKind

Category of the error.

limit?ProviderLimit

Set when the provider refused for a rate limit, a spent quota or overload; message is then describeProviderLimit's.

message?string

Optional human-readable message override. Falls back to the underlying error's message.

providerCode?string

Upstream error code as surfaced by the provider (e.g. context_length_exceeded). Optional.

retryable?boolean

Hint that the error is transient and a retry with backoff is reasonable (e.g. 429, 5xx, truncated stream). Omitted when the provider can't decide; callers should default to "do not retry" when absent to avoid hammering terminal failures (auth, invalid request).

src/errors.ts:16

Types#

AuthFailureKindType#

Why a sign-in stopped working:

  • expired: the refresh failed for a reason that signing in again fixes.
  • revoked: the grant was revoked or rejected (invalid_grant).
  • missing: no credential is stored (or the pinned account is gone).
  • busy: another process holds the refresh lock and has not let go.
  • network: the refresh could not reach the provider; retrying may do.
  • rejected: the provider refused the credential it was sent (a 401).
TypeScript
type AuthFailureKind =
  | 'expired'
  | 'revoked'
  | 'missing'
  | 'busy'
  | 'network'
  | 'rejected'

src/errors.ts:58

ClassifiedErrorKindType#

Kind of classified provider error

TypeScript
type ClassifiedErrorKind =
  | 'context_exceeded'
  | 'provider_error'
  | 'aborted'
  | 'tool_pairing_corruption'

src/errors.ts:13