{"id":"31e357158b0792d2","repo":"pydantic/pydantic","slug":"on-field-field-name-the-following-field-constr","errorCode":null,"errorMessage":"On field \"{field_name}\" the following field constraints are set but not enforced: {\", \".join(unused_constraints)}. \nFor more details see https://docs.pydantic.dev/usage/schema/#unenforced-field-constraints","messagePattern":"On field \"(.+?)\" the following field constraints are set but not enforced: (.+?)\\. \nFor more details see https://docs\\.pydantic\\.dev/usage/schema/#unenforced-field-constraints","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pydantic/v1/schema.py","lineNumber":1021,"sourceCode":") -> Type[Any]:\n    \"\"\"\n    Get an annotation with validation implemented for numbers and strings based on the field_info.\n    :param annotation: an annotation from a field specification, as ``str``, ``ConstrainedStr``\n    :param field_info: an instance of FieldInfo, possibly with declarations for validations and JSON Schema\n    :param field_name: name of the field for use in error messages\n    :param validate_assignment: default False, flag for BaseModel Config value of validate_assignment\n    :return: the same ``annotation`` if unmodified or a new annotation with validation in place\n    \"\"\"\n    constraints = field_info.get_constraints()\n    used_constraints: Set[str] = set()\n    if constraints:\n        annotation, used_constraints = get_annotation_with_constraints(annotation, field_info)\n    if validate_assignment:\n        used_constraints.add('allow_mutation')\n\n    unused_constraints = constraints - used_constraints\n    if unused_constraints:\n        raise ValueError(\n            f'On field \"{field_name}\" the following field constraints are set but not enforced: '\n            f'{\", \".join(unused_constraints)}. '\n            f'\\nFor more details see https://docs.pydantic.dev/usage/schema/#unenforced-field-constraints'\n        )\n\n    return annotation\n\n\ndef get_annotation_with_constraints(annotation: Any, field_info: FieldInfo) -> Tuple[Type[Any], Set[str]]:  # noqa: C901\n    \"\"\"\n    Get an annotation with used constraints implemented for numbers and strings based on the field_info.\n\n    :param annotation: an annotation from a field specification, as ``str``, ``ConstrainedStr``\n    :param field_info: an instance of FieldInfo, possibly with declarations for validations and JSON Schema\n    :return: the same ``annotation`` if unmodified or a new annotation along with the used constraints.\n    \"\"\"\n    used_constraints: Set[str] = set()\n","sourceCodeStart":1003,"sourceCodeEnd":1039,"githubUrl":"https://github.com/pydantic/pydantic/blob/2e5f0e2b4218de31709f1cf9c5bc61ea97a68835/pydantic/v1/schema.py#L1003-L1039","documentation":"Raised as `ValueError` by `get_annotation_from_field_info` when constraints declared on a `Field(...)` are not actually applicable to the field's type. pydantic computes `constraints - used_constraints`; if anything is left over (e.g. `gt` on an `int` is fine, but `max_length` on an `int`, or `regex` on a number), it refuses to silently ignore them.","triggerScenarios":"Declaring a Field with constraints that do not match the annotated type — e.g. `x: int = Field(min_length=4)`, `x: float = Field(regex='...')`, or `x: str = Field(gt=0)` (gt is numeric-only and unused on str). Also when applying a constraint that only exists for schema but not validation on an unsupported type.","commonSituations":"Copying a Field definition from another field of a different type, using a validator-style constraint on the wrong type, or assuming constraints are silently ignored if inapplicable.","solutions":["Remove or correct the constraint that does not apply to the annotated type (see the unused list in the message).","Move the validation into a @validator if you genuinely need it on that type.","Re-read the message: it names exactly which constraints are unenforced."],"exampleFix":"// before\nclass M(BaseModel):\n    age: int = Field(min_length=1)   # min_length is for strings\n\n// after\nclass M(BaseModel):\n    age: int = Field(ge=1)","handlingStrategy":"validation","validationCode":"# map of which constraints apply to which base type\n_STR = {'min_length','max_length','regex'}\n_NUM = {'gt','ge','lt','le','multiple_of'}\ndef constraints_match(type_, used) -> bool:\n    import numbers\n    return used <= (_STR if isinstance(type_, type) and issubclass(type_, str)\n                   else _NUM if isinstance(type_, type) and issubclass(type_, numbers.Number) else set())","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Match Field constraints to the field's primitive type (length->str/bytes, bounds->number).","Treat leftover constraints as a bug, not a no-op."],"tags":["validation","schema","constraints"],"analyzedSha":"2e5f0e2b4218de31709f1cf9c5bc61ea97a68835","analyzedAt":"2026-08-04T19:54:21.281Z","schemaVersion":2}