Skip to main content

Error Handling & Reporting

Pydantic distinguishes between two primary categories of errors: Validation Errors, which occur when input data does not conform to the defined schema, and User Errors, which occur when the library is used incorrectly by the developer.

Validation Errors

The ValidationError class (re-exported from pydantic_core) is the primary exception raised when validation fails. It is designed to be machine-readable while providing helpful information for human debugging.

Catching and Inspecting Errors

When a BaseModel or TypeAdapter fails to validate input, it raises a ValidationError. You can inspect the specific failures using the .errors() and .json() methods.

from pydantic import BaseModel, ValidationError

class User(BaseModel):
id: int
name: str

try:
User(id='not-an-int', name=123)
except ValidationError as e:
# Returns a list of ErrorDetails (TypedDict)
print(e.errors())

# Returns a JSON string representation of the errors
print(e.json(indent=2))

Error Details Structure

Each error in the list returned by .errors() follows the ErrorDetails structure:

  • type: A machine-readable identifier for the error (e.g., int_parsing, string_type).
  • loc: A tuple representing the path to the failing field (e.g., ('id',) or ('users', 0, 'name')).
  • msg: A human-readable message describing the error.
  • input: The actual value that failed validation.
  • ctx: (Optional) A dictionary containing context for the error (e.g., the limit for a greater_than error).
  • url: (Optional) A link to the Pydantic documentation for that specific error type.

Customizing Validation Errors

Pydantic allows you to customize error reporting within validators by raising standard Python exceptions or specialized Pydantic error classes.

Raising Standard Exceptions

If you raise a ValueError or AssertionError inside a @field_validator or @model_validator, Pydantic wraps it into a ValidationError with a type of value_error or assertion_error.

from pydantic import BaseModel, field_validator

class Model(BaseModel):
a: str

@field_validator('a')
@classmethod
def ensure_foobar(cls, v: str):
if 'foobar' not in v:
raise ValueError('"foobar" not found in a')
return v

PydanticCustomError

For more control over the error type and message templates, use PydanticCustomError from pydantic_core. This allows you to define a custom error slug and use curly braces for context injection.

from pydantic_core import PydanticCustomError
from pydantic import BaseModel, field_validator

class Model(BaseModel):
value: int

@field_validator('value')
@classmethod
def check_value(cls, v: int):
if v <= 10:
raise PydanticCustomError(
'custom_value_error',
'Value {input} must be greater than {limit}',
{'limit': 10, 'input': v}
)
return v

PydanticKnownError

PydanticKnownError is used when you want to raise one of Pydantic's built-in error types but provide your own context. This is frequently used in internal validators (found in pydantic/_internal/_validators.py) to raise standard errors like finite_number or greater_than.

from pydantic_core import PydanticKnownError

# Raising a built-in error with custom context
raise PydanticKnownError('greater_than', {'gt': 42})

Advanced Control Flow

Pydantic provides sentinel exceptions that allow validators to alter the validation flow instead of just reporting errors.

PydanticOmit

Raising PydanticOmit signals that the current field or item should be silently omitted from the output. This is particularly useful for filtering collections during validation.

from pydantic_core import PydanticOmit
from pydantic import BaseModel, field_validator

class Model(BaseModel):
items: list[int]

@field_validator('items', mode='after')
@classmethod
def filter_even(cls, v: list[int]):
# In a real scenario, this might be used inside a per-item validator
# to skip specific elements.
return [i for i in v if i % 2 != 0]

PydanticUseDefault

Raising PydanticUseDefault tells Pydantic to stop validation for the current field and use its defined default value instead.

from pydantic_core import PydanticUseDefault
from pydantic import BaseModel, field_validator

class Model(BaseModel):
a: int = 42

@field_validator('a', mode='before')
@classmethod
def use_default_if_none(cls, v):
if v is None:
raise PydanticUseDefault()
return v

Developer Errors (PydanticUserError)

Errors caused by incorrect model definitions or library usage raise PydanticUserError (defined in pydantic/errors.py). These are RuntimeError subclasses and are not intended to be caught during normal data processing.

Common subclasses include:

  • PydanticUndefinedAnnotation: Raised when a type annotation cannot be resolved.
  • PydanticSchemaGenerationError: Raised when Pydantic cannot generate a CoreSchema for a specific type.
  • PydanticImportError: Raised when attempting to use V1 features that have been moved or removed in V2.

These errors include a code that links to detailed documentation at https://errors.pydantic.dev/.

Configuration

The inclusion of documentation URLs in ValidationError messages can be controlled via the PYDANTIC_ERRORS_INCLUDE_URL environment variable.

  • PYDANTIC_ERRORS_INCLUDE_URL=1 (default): Includes URLs in the error repr.
  • PYDANTIC_ERRORS_INCLUDE_URL=0: Omits URLs.

This setting must be configured before the first ValidationError is instantiated in the process.