Add `ToolFailed` for model-visible failures without retries
Merged
AD
4mo ago+2195+2195+0123456789012345678901234567890123456789-172-172-012345678901234567890123456789
Summary
Adds ToolFailed, a public exception for reporting a completed tool failure to the model without consuming the tool retry budget or ending the agent run.
Raising ToolFailed(message) produces a ToolReturnPart with outcome='failed'. Parallel successful tool calls still complete, the failure is visible in telemetry, and the model can choose whether to retry, use another tool, or answer with the partial results.
from pydantic_ai import Agent, ToolFailed
agent = Agent('openai:gpt-5')
@agent.tool_plain
def fetch(url: str) -> str:
if down(url):
raise ToolFailed(f'{url} is unavailable')
return get(url)
Included
- Public
ToolFailedsupport in tool bodies, argument validators, capability hooks, deferred execution, and tool-manager raw mode. - Native failed-result mapping for Anthropic, Bedrock, and Google.
- Explicit
{"error": ...}JSON framing for providers without a native tool-error channel. - Current
ToolReturnPart.outcomesemantics acrosssuccess,failed,denied, andinterrupted. - AG-UI and Vercel AI round-tripping for non-success outcomes.
- Temporal, DBOS, and Prefect handling.
- Opt-in
MCPToolset(tool_error_behavior='failed'), including model-visible structured MCP error details. The existing default remains'retry'. - Documentation and bundled Pydantic AI agent-skill updates.
Supersedes
- #5353, which targeted MCP
isErrorresults. - #5871, which targeted AG-UI failed/denied outcome round-tripping.
Follow-ups
These remain separate from this PR, as discussed with maintainers:
- Retry first, then report a failed result when retries are exhausted.
- Revisit timeout behavior.
- Disable a tool after failure.
Checklist
- Any AI generated code has been reviewed line-by-line by the human PR author, who stands by it.
- No breaking changes in accordance with the version policy.
- PR title is fit for the release changelog.