Skip to content

pydantic_ai.exceptions

ModelRetry

Bases: Exception

Exception to raise when a tool function should be retried.

The agent will return the message to the model and ask it to try calling the function/tool again.

Source code in pydantic_ai_slim/pydantic_ai/exceptions.py
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
class ModelRetry(Exception):
    """Exception to raise when a tool function should be retried.

    The agent will return the message to the model and ask it to try calling the function/tool again.
    """

    message: str
    """The message to return to the model."""

    def __init__(self, message: str):
        self.message = message
        super().__init__(message)

    def __eq__(self, other: Any) -> bool:
        return isinstance(other, self.__class__) and other.message == self.message

    def __hash__(self) -> int:
        return hash((self.__class__, self.message))

    @classmethod
    def __get_pydantic_core_schema__(cls, _: Any, __: Any) -> core_schema.CoreSchema:
        """Pydantic core schema to allow `ModelRetry` to be (de)serialized."""
        schema = core_schema.typed_dict_schema(
            {
                'message': core_schema.typed_dict_field(core_schema.str_schema()),
                'kind': core_schema.typed_dict_field(core_schema.literal_schema(['model-retry'])),
            }
        )
        return core_schema.no_info_after_validator_function(
            lambda dct: ModelRetry(dct['message']),
            schema,
            serialization=core_schema.plain_serializer_function_ser_schema(
                lambda x: {'message': x.message, 'kind': 'model-retry'},
                return_schema=schema,
            ),
        )

message instance-attribute

message: str = message

The message to return to the model.

__get_pydantic_core_schema__ classmethod

__get_pydantic_core_schema__(_: Any, __: Any) -> CoreSchema

Pydantic core schema to allow ModelRetry to be (de)serialized.

Source code in pydantic_ai_slim/pydantic_ai/exceptions.py
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
@classmethod
def __get_pydantic_core_schema__(cls, _: Any, __: Any) -> core_schema.CoreSchema:
    """Pydantic core schema to allow `ModelRetry` to be (de)serialized."""
    schema = core_schema.typed_dict_schema(
        {
            'message': core_schema.typed_dict_field(core_schema.str_schema()),
            'kind': core_schema.typed_dict_field(core_schema.literal_schema(['model-retry'])),
        }
    )
    return core_schema.no_info_after_validator_function(
        lambda dct: ModelRetry(dct['message']),
        schema,
        serialization=core_schema.plain_serializer_function_ser_schema(
            lambda x: {'message': x.message, 'kind': 'model-retry'},
            return_schema=schema,
        ),
    )

CallDeferred

Bases: Exception

Exception to raise when a tool call should be deferred.

See tools docs for more information.

Parameters:

Name Type Description Default
metadata dict[str, Any] | None

Optional dictionary of metadata to attach to the deferred tool call. This metadata will be available in DeferredToolRequests.metadata keyed by tool_call_id.

None
Source code in pydantic_ai_slim/pydantic_ai/exceptions.py
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
class CallDeferred(Exception):
    """Exception to raise when a tool call should be deferred.

    See [tools docs](../deferred-tools.md#deferred-tools) for more information.

    Args:
        metadata: Optional dictionary of metadata to attach to the deferred tool call.
            This metadata will be available in `DeferredToolRequests.metadata` keyed by `tool_call_id`.
    """

    def __init__(self, metadata: dict[str, Any] | None = None):
        self.metadata = metadata
        super().__init__()

    def __reduce__(self) -> tuple[type, tuple[Any, ...]]:
        return self.__class__, (self.metadata,)

ApprovalRequired

Bases: Exception

Exception to raise when a tool call requires human-in-the-loop approval.

See tools docs for more information.

Parameters:

Name Type Description Default
metadata dict[str, Any] | None

Optional dictionary of metadata to attach to the deferred tool call. This metadata will be available in DeferredToolRequests.metadata keyed by tool_call_id.

None
Source code in pydantic_ai_slim/pydantic_ai/exceptions.py
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
class ApprovalRequired(Exception):
    """Exception to raise when a tool call requires human-in-the-loop approval.

    See [tools docs](../deferred-tools.md#human-in-the-loop-tool-approval) for more information.

    Args:
        metadata: Optional dictionary of metadata to attach to the deferred tool call.
            This metadata will be available in `DeferredToolRequests.metadata` keyed by `tool_call_id`.
    """

    def __init__(self, metadata: dict[str, Any] | None = None):
        self.metadata = metadata
        super().__init__()

    def __reduce__(self) -> tuple[type, tuple[Any, ...]]:
        return self.__class__, (self.metadata,)

UserError

Bases: RuntimeError

Error caused by a usage mistake by the application developer — You!

Source code in pydantic_ai_slim/pydantic_ai/exceptions.py
110
111
112
113
114
115
116
117
118
class UserError(RuntimeError):
    """Error caused by a usage mistake by the application developer — You!"""

    message: str
    """Description of the mistake."""

    def __init__(self, message: str):
        self.message = message
        super().__init__(message)

message instance-attribute

message: str = message

Description of the mistake.

AgentRunError

Bases: RuntimeError

Base class for errors occurring during an agent run.

Source code in pydantic_ai_slim/pydantic_ai/exceptions.py
121
122
123
124
125
126
127
128
129
130
131
132
class AgentRunError(RuntimeError):
    """Base class for errors occurring during an agent run."""

    message: str
    """The error message."""

    def __init__(self, message: str):
        self.message = message
        super().__init__(message)

    def __str__(self) -> str:
        return self.message

message instance-attribute

message: str = message

The error message.

UsageLimitExceeded

Bases: AgentRunError

Error raised when a Model's usage exceeds the specified limits.

Source code in pydantic_ai_slim/pydantic_ai/exceptions.py
135
136
class UsageLimitExceeded(AgentRunError):
    """Error raised when a Model's usage exceeds the specified limits."""

ConcurrencyLimitExceeded

Bases: AgentRunError

Error raised when the concurrency queue depth exceeds max_queued.

Source code in pydantic_ai_slim/pydantic_ai/exceptions.py
139
140
class ConcurrencyLimitExceeded(AgentRunError):
    """Error raised when the concurrency queue depth exceeds max_queued."""

UnexpectedModelBehavior

Bases: AgentRunError

Error caused by unexpected Model behavior, e.g. an unexpected response code.

Source code in pydantic_ai_slim/pydantic_ai/exceptions.py
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
class UnexpectedModelBehavior(AgentRunError):
    """Error caused by unexpected Model behavior, e.g. an unexpected response code."""

    message: str
    """Description of the unexpected behavior."""
    body: str | None
    """The body of the response, if available."""

    def __init__(self, message: str, body: str | None = None):
        self.message = message
        if body is None:
            self.body: str | None = None
        else:
            try:
                self.body = json.dumps(json.loads(body), indent=2)
            except ValueError:
                self.body = body
        super().__init__(message)

    def __reduce__(self) -> tuple[type, tuple[Any, ...]]:
        return self.__class__, (self.message, self.body)

    def __str__(self) -> str:
        if self.body:
            return f'{self.message}, body:\n{self.body}'
        else:
            return self.message

message instance-attribute

message: str = message

Description of the unexpected behavior.

body instance-attribute

body: str | None = dumps(loads(body), indent=2)

The body of the response, if available.

ContentFilterError

Bases: UnexpectedModelBehavior

Raised when content filtering is triggered by the model provider resulting in an empty response.

Source code in pydantic_ai_slim/pydantic_ai/exceptions.py
172
173
class ContentFilterError(UnexpectedModelBehavior):
    """Raised when content filtering is triggered by the model provider resulting in an empty response."""

ModelAPIError

Bases: AgentRunError

Raised when a model provider API request fails.

Source code in pydantic_ai_slim/pydantic_ai/exceptions.py
176
177
178
179
180
181
182
183
184
185
186
187
class ModelAPIError(AgentRunError):
    """Raised when a model provider API request fails."""

    model_name: str
    """The name of the model associated with the error."""

    def __init__(self, model_name: str, message: str):
        self.model_name = model_name
        super().__init__(message)

    def __reduce__(self) -> tuple[type, tuple[Any, ...]]:
        return self.__class__, (self.model_name, self.message)

model_name instance-attribute

model_name: str = model_name

The name of the model associated with the error.

ModelHTTPError

Bases: ModelAPIError

Raised when an model provider response has a status code of 4xx or 5xx.

Source code in pydantic_ai_slim/pydantic_ai/exceptions.py
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
class ModelHTTPError(ModelAPIError):
    """Raised when an model provider response has a status code of 4xx or 5xx."""

    status_code: int
    """The HTTP status code returned by the API."""

    body: object | None
    """The body of the response, if available."""

    def __init__(self, status_code: int, model_name: str, body: object | None = None):
        self.status_code = status_code
        self.body = body
        message = f'status_code: {status_code}, model_name: {model_name}, body: {body}'
        super().__init__(model_name=model_name, message=message)

    def __reduce__(self) -> tuple[type, tuple[Any, ...]]:
        return self.__class__, (self.status_code, self.model_name, self.body)

status_code instance-attribute

status_code: int = status_code

The HTTP status code returned by the API.

body instance-attribute

body: object | None = body

The body of the response, if available.

FallbackExceptionGroup

Bases: ExceptionGroup[Any]

A group of exceptions that can be raised when all fallback models fail.

Source code in pydantic_ai_slim/pydantic_ai/exceptions.py
209
210
class FallbackExceptionGroup(ExceptionGroup[Any]):
    """A group of exceptions that can be raised when all fallback models fail."""

ToolRetryError

Bases: Exception

Exception used to signal a ToolRetry message should be returned to the LLM.

Source code in pydantic_ai_slim/pydantic_ai/exceptions.py
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
class ToolRetryError(Exception):
    """Exception used to signal a `ToolRetry` message should be returned to the LLM."""

    def __init__(self, tool_retry: RetryPromptPart):
        self.tool_retry = tool_retry
        message = (
            tool_retry.content
            if isinstance(tool_retry.content, str)
            else self._format_error_details(tool_retry.content, tool_retry.tool_name)
        )
        super().__init__(message)

    def __reduce__(self) -> tuple[type, tuple[Any, ...]]:
        return self.__class__, (self.tool_retry,)

    @staticmethod
    def _format_error_details(errors: list[pydantic_core.ErrorDetails], tool_name: str | None) -> str:
        """Format ErrorDetails as a human-readable message.

        We format manually rather than using ValidationError.from_exception_data because
        some error types (value_error, assertion_error, etc.) require an 'error' key in ctx,
        but when ErrorDetails are serialized, exception objects are stripped from ctx.
        The 'msg' field already contains the human-readable message, so we use that directly.
        """
        error_count = len(errors)
        lines = [
            f'{error_count} validation error{"" if error_count == 1 else "s"}{f" for {tool_name!r}" if tool_name else ""}'
        ]
        for e in errors:
            loc = '.'.join(str(x) for x in e['loc']) if e['loc'] else '__root__'
            lines.append(loc)
            lines.append(f'  {e["msg"]} [type={e["type"]}, input_value={e["input"]!r}]')
        return '\n'.join(lines)

IncompleteToolCall

Bases: UnexpectedModelBehavior

Error raised when a model stops due to token limit while emitting a tool call.

Source code in pydantic_ai_slim/pydantic_ai/exceptions.py
248
249
class IncompleteToolCall(UnexpectedModelBehavior):
    """Error raised when a model stops due to token limit while emitting a tool call."""