Skip to main content

Customizing Error Responses in Schemas

To customize validation error responses in this codebase, you can use core_schema.custom_error_schema to wrap existing schemas and override their default error types, messages, and context. This is useful for providing domain-specific error identifiers and human-readable messages.

Overriding Errors in a Schema​

The most direct way to customize an error is to wrap a CoreSchema with custom_error_schema. This ensures that any validation failure within the wrapped schema returns your specified error details.

from pydantic_core import SchemaValidator, core_schema

# Wrap an integer schema with a custom error
schema = core_schema.custom_error_schema(
core_schema.int_schema(),
custom_error_type='my_custom_error',
custom_error_message='The provided value must be a valid integer'
)

v = SchemaValidator(schema)

try:
v.validate_python('not-an-int')
except Exception as exc:
# The error now uses the custom type and message
print(exc.errors())
# Output: [{'type': 'my_custom_error', 'loc': (), 'msg': 'The provided value must be a valid integer', 'input': 'not-an-int'}]

Key Configuration Fields​

When using CustomErrorSchema (via the core_schema.custom_error_schema helper), you can configure the following:

  • custom_error_type: A string identifier (slug) for the error. This is used programmatically to identify the error type.
  • custom_error_message: A human-readable string. If not provided, and the type matches a known Pydantic error, the default message for that type is used.
  • custom_error_context: A dictionary of values (strings, ints, or floats) that can be used to provide additional metadata about the error.

Manual Error Generation​

If you need to generate validation errors programmatically (for example, in a custom validator or when re-raising errors), use InitErrorDetails with ValidationError.from_exception_data.

from pydantic_core import ValidationError, InitErrorDetails

errors = [
InitErrorDetails(
type='value_error',
loc=('field_name',),
input='invalid_input',
ctx={'reason': 'Value is too long'}
)
]

# Manually create a ValidationError
raise ValidationError.from_exception_data('MyModel', errors)

Using Known Error Types​

You can use custom_error_schema to trigger standard Pydantic errors even if the underlying schema doesn't naturally produce them. However, there is a restriction: if the custom_error_type matches a built-in error type (like recursion_loop), you cannot provide a custom_error_message.

from pydantic_core import SchemaValidator, core_schema

# This is valid: it uses the default message for 'recursion_loop'
schema = core_schema.custom_error_schema(
core_schema.int_schema(),
'recursion_loop'
)

v = SchemaValidator(schema)
# Validation failure will result in:
# {'type': 'recursion_loop', 'msg': 'Recursion error - cyclic reference detected', ...}

Troubleshooting​

SchemaError: custom_error_message should not be provided​

If you attempt to provide a custom_error_message while using a custom_error_type that matches a known Pydantic error, a SchemaError will be raised during validator initialization.

from pydantic_core import SchemaValidator, core_schema, SchemaError
import pytest

# This will raise a SchemaError
with pytest.raises(SchemaError, match="custom_error_message should not be provided"):
SchemaValidator(
core_schema.custom_error_schema(
core_schema.int_schema(),
'recursion_loop',
custom_error_message='Custom message'
)
)

Accessing Processed Error Details​

When a ValidationError is caught, you can retrieve the structured ErrorDetails by calling .errors(). This converts the internal error representation into a list of dictionaries containing the type, loc, msg, input, and optional ctx and url.

try:
v.validate_python(input_data)
except ValidationError as exc:
error_list = exc.errors(include_url=False, include_context=True)
for error in error_list:
print(f"Error Type: {error['type']}, Message: {error['msg']}")