Skip to main content

Error Recovery for AI Agents

This package ships error handling and recovery patterns for improved reliability of AI Agents, as a native Pydantic AI 2.0 capability.

Motivation

Agentic tool calling can fail for many reasons, and adding error handling and retries to every tool is cumbersome. For third-party tools and MCPs, it's often impossible. ToolErrorRecovery is a standardized capability for AI agents to recover from errors during tool calls. Similar in spirit to FastAPI's exception handlers, but for agents.

This package combines the ideas and vocabulary of pydantic-ai-harness PR #171 with its own mechanics: it uses a classify callable rather than a per-tool strategy map for more flexibility; a single wrap_tool_execute hook rather than two; and does not expose str(error) to the agent by default for added security. It is intended as a stand-alone capability, but also as a proposal of how to make progress on PR #171.

Quick Start

pip install pydantic-ai-error-recovery
from pydantic_ai import Agent
from pydantic_ai_error_recovery import ToolErrorRecovery

agent = Agent('openai:gpt-5', capabilities=[ToolErrorRecovery()])

Out of the box, connection errors are retried, bugs are propagated, and everything else is reported to the model, preventing a crash of the agent run. Continue reading to learn how to customize the capability.

Features

The ToolErrorRecovery capability supports four different recovery outcomes:

Outcome Effect
retry Re-attempt the tool call a number of times (invisible to the model)
inform Report a terminal failure to the model via ToolFailed (outcome='failed')
fallback Return a substitute value as the tool result
propagate Re-raise the exception, will crash the run unless caught by another wrapper

Error Classification

ToolErrorRecovery intercepts tool execution errors and applies a per-error reaction. A classify callable you supply inspects each failure and returns the intended recovery outcome:

def classify(ctx: RunContext[Any], call: ToolCallPart, error: BaseException) -> RecoveryOutcome:
    if isinstance(error, SomeException):
        return RecoveryOutcome.inform(
            label='Tool call ran into SomeException',
            expose_message=False,
        )
    # and so on

Notes:

  • You can classify on a tool's name and other properties of the tool call, on the exception type, or both.
  • The ctx: RunContext parameter is included for cases in which your classification logic additionally depends on the run context.
  • To not interfere with existing error handling, the following exceptions from the Pydantic AI control flow are never classified: SkipToolExecution, CallDeferred, ApprovalRequired, ModelRetry, ToolRetryError, ToolFailed, and ToolFailedError.
  • Special care must be taken when classifying an exception which is a subclass, be careful about the order of isinstance(...) calls, or use type(...) is instead.

Default Behaviour

As mentioned above, control flow exceptions are never classified. Our default classifier is:

def classify(ctx: RunContext[Any], call: ToolCallPart, error: BaseException) -> RecoveryOutcome:
    if isinstance(error, DEFAULT_BUG_TYPES):
        return RecoveryOutcome.propagate()
    if isinstance(error, HookTimeoutError):
        return RecoveryOutcome.inform()
    if isinstance(error, DEFAULT_TRANSIENT_TYPES):
        return RecoveryOutcome.retry(3)
    return RecoveryOutcome.inform()

The classification function is the key piece required to construct your own RecoveryPolicy via RecoveryPolicy(classify=classify). A fully custom example could look like this:

from pydantic_ai import Agent
from pydantic_ai_error_recovery import ToolErrorRecovery

def classify(...):
    # your classification logic

agent = Agent('openai:gpt-5', capabilities=[
    ToolErrorRecovery(
        policy=RecoveryPolicy(
            classify=classify,
            format_error=my_formatter,
            max_message_len=450,
            include_traceback=False,
            logger=my_logger,
        ),
        max_recoveries=10,
        per_tool_recoveries={'my_tool_name': 5},
    )
])

Contributing

We welcome community contributions under Apache-2.0. Please create an issue to discuss an improvement, or submit a pull request. Clone the repository, then run:

make install   # uv sync --extra dev
make all       # lint, format, typecheck, and tests with 100% branch coverage

Please ensure that make all passes before committing. Coding standards, file layout, and testing patterns can be found in AGENTS.md.

License

Apache-2.0

Metadata

Release files for pydantic-ai-error-recovery 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pydantic-ai-error-recovery 0.2.0
File Size Uploaded
pydantic_ai_error_recovery-0.2.0.tar.gz 60.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pydantic-ai-error-recovery 0.2.0
File Interpreter ABI Platform
pydantic_ai_error_recovery-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 77.1 kB

Release files / pydantic_ai_error_recovery-0.2.0.tar.gz

Download URL pydantic_ai_error_recovery-0.2.0.tar.gz
Size 60.0 kB
Tags Source
SHA-256 checksum
How to use checksums
ad5a5190d232dfe98e811787881cff3a0ce483e2547791e5d8d1290d6a6dd9cd
BLAKE2b-256 checksum
How to use checksums
b92fc9dc60418ddcd99f31027c553d931a48ff5e20927218193021b8052f6bbd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

Release files / pydantic_ai_error_recovery-0.2.0-py3-none-any.whl

Download URL pydantic_ai_error_recovery-0.2.0-py3-none-any.whl
Size 17.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dc0d6be0b6fa2bf481181f05782ca75867bee85dcfd6b192dcbd7a056bbfd58c
BLAKE2b-256 checksum
How to use checksums
82e86833342f1ef1aa4b0f64135803f5f4733ef6f93ea906b6d889d15ef85c0b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page