The hierarchy is shallow, eighteen classes, with rich structured fields, because callers
branch on fields far more often than on exception class:
exceptai.AnyInferErroraserror:error.detail# what happened; redacted, ≤512 charserror.hint# the actionable next step, when one existserror.provider# which provider, when applicableerror.phase# configure | discover | generate | stream | validate | cleanuperror.retryable# would repeating this identical request help?error.retry_after_s# server-advised delay, when suppliederror.http_status# status code, for HTTP-sourced failures
detail and hint always pass redaction, so no error can leak a credential no matter where
it is logged.
AnyInferError
├── ConfigError bad config, target, catalog, or a missing extra
├── CredentialError a credential reference could not be resolved
├── ProviderError base for anything a provider surfaced
│ ├── AuthError
│ ├── RateLimitError
│ ├── ModelNotFoundError
│ ├── ContextLengthError
│ ├── TransportError
│ ├── StreamProtocolError
│ ├── ProviderUnavailableError
│ └── UnsupportedInputError
├── SpendLimitError a caller-set spending ceiling would be crossed
├── SchemaViolationError validation failed after the repair budget
├── ToolLoopError unknown tool, bad signature, or round bound exceeded
├── AllTargetsFailedError the router exhausted every target
└── LocalRuntimeError llama-server lifecycle, or model integrity
└── ConfidentialExecutionError the attested guarantee isn't available on this host
ProviderError is a distinct branch on purpose: it is exactly what the router catches and
may retry. ConfigError, SchemaViolationError, and AllTargetsFailedError are not
provider errors and propagate straight to the caller.
When: an unknown target or provider, a malformed catalog, a missing required setting, or
a provider whose optional extra is not installed.
Retryable: no.
ConfigError: unknown target 'gpt-5'
(hint: use 'provider:model' (e.g. 'anthropic:claude-sonnet-4-5'), or one of these
aliases: large, medium, small)
ConfigError: the copilot provider requires the github-copilot-sdk extra
(hint: pip install 'anyinfer[copilot]', then run 'copilot login')
embed() and rerank() raise no exception types of their own: an unsupported operation,
a refused embedding fallback, or an oversized batch is a ConfigError whose message and
hint name the rule that refused it. The rule behind fallback refusals is
the embedding-space safety rule.
When: the prompt exceeds the model's context window.
Retryable: no; the same prompt is the same size. Use Route.context_window_targets to
fall back to a larger model instead, or trim the prompt with
token estimation and context budgets.
When: a timeout, connection failure, or TLS error. No usable response arrived.
Retryable: yes. Since nothing was delivered, a retry cannot duplicate output the
consumer already saw (the boundary that makes StreamProtocolError different). See
the event stream.
TransportError: request to ollama timed out
(hint: raise timeout_s, or choose a faster model)
When: malformed SSE/NDJSON framing, or a response exceeding max_response_bytes.
Retryable: no by default. If content had already been emitted, this is raised rather
than retried: the consumer has seen text, and silently restarting would duplicate or
contradict it. The framing and ordering guarantees are in
the event stream.
When: a trusted model capability proves the target cannot accept an attached input
modality (image, document, or audio). Raised before dispatch.
Retryable: no; the same attachment against the same target fails the same way. What
each provider accepts is covered in
multimodal inputs.
UnsupportedInputError: ollama cannot project audio input (model reports no audio support)
(hint: choose a target that supports this input form or supply supported inline bytes)
When: a request would cross a caller-set max_request_usd or max_total_usd spending
ceiling, or its cost cannot be estimated and the policy says not to spend blind. Raised
before dispatch, so nothing was sent and nothing was billed.
Retryable: no; deterministic by construction: the identical request refused once will
be refused again.
SpendLimitError: a request to anthropic:claude-sonnet-4-5 could cost 0.42, above the
per-request ceiling of 0.25
(hint: shorten the prompt, cap max_output_tokens, or raise max_request_usd)
How to fix
Read error.hint, and inspect error.limit_usd, error.spent_usd, and
error.estimated_usd for the exact numbers behind the refusal. See
cost and spending.
When: the response failed validation and the repair budget is spent.
Retryable: no, and not a routing failure: the request reached the model and the model
answered; it answered the wrong shape.
exceptai.SchemaViolationErroraserror:error.raw_text# what the model actually saiderror.errors# ("age: 'age' is a required property",)
How to fix
Increase Repair.max_attempts, simplify the schema, inspect error.partial and
error.missing_required, or debug the bounded error.raw_text. Partial members are not
schema-validated and no truncated value is guessed.
See structured output.
When: llama-server failed to start, crashed, timed out becoming ready, could not be
reaped, or a model artifact failed hash verification.
LocalRuntimeError: llama-server exited with code 3 while loading qwen2.5-7b:
fatal: unable to load model
(hint: the model may be incompatible with this runtime build, or the machine may
have run out of memory)
The server's own log tail is included, because polling a health endpoint alone reveals
nothing about why it failed.
How to fix
Read the included log tail first; it usually names the real cause (OOM, an
incompatible GGUF, a port conflict). See the local subsystem.
When:ConfidentialExecutionAdapter.generate() was called and
anyinfer.local.confidential_execution_status() reported end_to_end=False for this
host. The inner local adapter is never called; this fails closed, not degraded.
ConfidentialExecutionError: confidential execution was requested but is not available:
no attestable CPU TEE detected (SEV-SNP/TDX guest device not present)
How to fix
Call confidential_execution_status() before committing to a request, so the
application can degrade with a message the caller sees instead of hitting this
error mid-call. See the
Confidentiality Tiers guide.
Four behaviors are reported as bugs often enough to state as intended:
A cost of None when pricing is unknown. Coercing it to zero would turn a reporting
gap into a silent accounting error; see cost and spending.
SchemaViolationError does not trigger fallback. The request reached the model and the
model answered; a different provider does not fix a shape problem.
A mid-stream protocol error after content was emitted raises rather than retries. The
consumer has already seen text.
An unrecognized finish reason does not crash. FinishReason is an open enum, and
unknown values normalize to "other".