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.
[!NOTE] This package is in early development, the API might still change before v1.0.
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.
Related Work
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: RunContextparameter 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, andToolFailedError. - Special care must be taken when classifying an exception which is a subclass, be careful about the order of
isinstance(...)calls, or usetype(...) isinstead.
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
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pydantic_ai_error_recovery-0.1.1.tar.gz.
File metadata
- Download URL: pydantic_ai_error_recovery-0.1.1.tar.gz
- Upload date:
- Size: 59.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9e42c92b463cbe1c193464eb91214ccfae67e99a0e21ec526b2aa15c48d27a7d
|
|
| MD5 |
2ef2c33c5fbe5a74c4ddd4812f2cdfd4
|
|
| BLAKE2b-256 |
fc8f342025a0b8229c89101b003e094b78ed6fd5fe09c0c5947450bb648f9299
|
Provenance
The following attestation bundles were made for pydantic_ai_error_recovery-0.1.1.tar.gz:
Publisher:
publish.yml on aixbrain/pydantic-ai-error-recovery
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydantic_ai_error_recovery-0.1.1.tar.gz -
Subject digest:
9e42c92b463cbe1c193464eb91214ccfae67e99a0e21ec526b2aa15c48d27a7d - Sigstore transparency entry: 2367638965
- Sigstore integration time:
-
Permalink:
aixbrain/pydantic-ai-error-recovery@2bedcfef5bda2292022fb07f40754cbc2b18f4e1 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/aixbrain
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2bedcfef5bda2292022fb07f40754cbc2b18f4e1 -
Trigger Event:
release
-
Statement type:
File details
Details for the file pydantic_ai_error_recovery-0.1.1-py3-none-any.whl.
File metadata
- Download URL: pydantic_ai_error_recovery-0.1.1-py3-none-any.whl
- Upload date:
- Size: 20.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7c3bc336b3bb98cb5bbbe24e04cac7883aa834afd5316c5ae7cb6e1aee152f9b
|
|
| MD5 |
87a611b34146a14eb4b8c48a927c2204
|
|
| BLAKE2b-256 |
e29e954857765be4efcf11259c0c6110f2eef3525fd71bdf1517de4c495d2bcf
|
Provenance
The following attestation bundles were made for pydantic_ai_error_recovery-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on aixbrain/pydantic-ai-error-recovery
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydantic_ai_error_recovery-0.1.1-py3-none-any.whl -
Subject digest:
7c3bc336b3bb98cb5bbbe24e04cac7883aa834afd5316c5ae7cb6e1aee152f9b - Sigstore transparency entry: 2367639010
- Sigstore integration time:
-
Permalink:
aixbrain/pydantic-ai-error-recovery@2bedcfef5bda2292022fb07f40754cbc2b18f4e1 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/aixbrain
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2bedcfef5bda2292022fb07f40754cbc2b18f4e1 -
Trigger Event:
release
-
Statement type: