Errors and privacy
Handle text and structured errors and review what their messages contain.
Choose structured errors explicitly
The default text mode raises ValueError. error_mode='structured' raises ValidationError, a ValueError subclass with an issues list. Each issue carries a string path, message, expected, and got. These legacy fields are preserved. Engine errors also expose a separate immutable details tuple of ValidationIssue records with machine codes and typed locations; manual legacy errors and unsupported key locations may have details=None. The canonical snapshot stays unchanged when issues is mutated.
from zodify import ValidationError, validate
try:
validate({"port": int}, {"port": "wrong"}, error_mode="structured")
except ValidationError as error:
print(error.issues[0])
{'path': 'port', 'message': 'expected int, got str', 'expected': 'int', 'got': 'str'}Treat error text as potentially sensitive
Coercion failures can include the original string, and custom callback exceptions can include callback messages. Avoid logging entire errors for credentials or user secrets; prefer an application-controlled message and a reviewed field identifier.
Legacy paths use dots and brackets. Literal field names containing punctuation can be ambiguous. Use each ValidationIssue record’s loc field in details for structural locations when available.