Configuring Error Reporting and Privacy
You can customize how validation errors are reported and protect sensitive data by configuring CoreConfig when initializing a SchemaValidator. This allows you to redact input values from error messages and preserve the original Python exceptions that caused a validation failure.
Hiding Sensitive Input Data
To prevent sensitive information (like passwords or PII) from appearing in logs or error representations, set hide_input_in_errors to True in your CoreConfig.
import re
import pytest
from pydantic_core import SchemaValidator, ValidationError, core_schema as cs, CoreConfig
# Define a schema that hides input data in errors
config = CoreConfig(hide_input_in_errors=True)
validator = SchemaValidator(
cs.model_schema(
cls=dict,
schema=cs.model_fields_schema(
fields={'password': cs.model_field(schema=cs.str_schema())}
)
),
config=config,
)
try:
# Attempt to validate an invalid type (int instead of str)
validator.validate_python({'password': 12345})
except ValidationError as exc:
# The error message will NOT contain 'input_value=12345'
assert 'input_value=12345' not in str(exc)
assert 'type=string_type' in str(exc)
# Structured errors also omit the 'input' key
for error in exc.errors():
assert 'input' not in error
When hide_input_in_errors is False (the default), the error representation includes the input value and type:
Input should be a valid string [type=string_type, input_value=12345, input_type=int]
When enabled, it is reduced to:
Input should be a valid string [type=string_type]
Preserving Original Exception Causes
When using custom validator functions, you can attach the original Python exception to the ValidationError by setting validation_error_cause to True. This is useful for debugging complex validation logic.
from pydantic_core import SchemaValidator, core_schema, CoreConfig, ValidationError
def custom_validator(v):
if v == "fail":
# This original exception will be preserved
raise ValueError("Internal validation logic failed")
return v
config = CoreConfig(validation_error_cause=True)
validator = SchemaValidator(
core_schema.no_info_plain_validator_function(custom_validator),
config=config
)
try:
validator.validate_python("fail")
except ValidationError as exc:
# The original ValueError is wrapped in an ExceptionGroup and attached to __cause__
cause_group = exc.__cause__
assert len(cause_group.exceptions) == 1
assert isinstance(cause_group.exceptions[0], ValueError)
assert str(cause_group.exceptions[0]) == "Internal validation logic failed"
Requirements for Exception Causes
- Python 3.11+: Uses the built-in
ExceptionGroup. - Python < 3.11: Requires the
exceptiongroupbackport package. If the package is missing andvalidation_error_causeis enabled, anImportErrorwill be raised during validation if an exception occurs.
Configuring Error Documentation Links
By default, pydantic-core includes a URL to the Pydantic documentation in the ValidationError string representation. You can control this globally using environment variables.
- Disable URLs: Set
PYDANTIC_ERRORS_INCLUDE_URL=0orPYDANTIC_ERRORS_INCLUDE_URL=false. - Enable URLs: Set
PYDANTIC_ERRORS_INCLUDE_URL=1(default).
[!IMPORTANT] Environment variables for error reporting must be set before
ValidationError.__repr__is called for the first time in your process to take effect.
Troubleshooting
Missing Input in Manual Errors
If you are manually raising a ValidationError using from_exception_data, you must pass the hide_input argument to match your schema's privacy settings:
from pydantic_core import ValidationError
# Manually redact input in a custom error
exc = ValidationError.from_exception_data(
'MyModel',
[{'type': 'greater_than', 'loc': ('val',), 'input': 4, 'ctx': {'gt': 5}}],
hide_input=True
)
assert 'input_value=4' not in str(exc)
Traceback Loss
If you find that tracebacks are missing when using validation_error_cause, ensure you are not catching and re-raising exceptions without the from keyword inside your custom validators. pydantic-core preserves the __cause__ chain of the exceptions it captures.