pydantic/pydantic · error · ValueError

cannot specify multiple `Annotated` `Field`s for {field_name

Error message

cannot specify multiple `Annotated` `Field`s for {field_name!r}

What it means

Raised by ModelField._get_field_info when a single field's typing.Annotated annotation contains more than one FieldInfo metadata entry. pydantic v1 allows at most one Field inside Annotated[...] because multiple FieldInfos would have conflicting constraints; the check counts isinstance(arg, FieldInfo) across the metadata args.

Source

Thrown at pydantic/v1/fields.py:461

        """
        Get a FieldInfo from a root typing.Annotated annotation, value, or config default.

        The FieldInfo may be set in typing.Annotated or the value, but not both. If neither contain
        a FieldInfo, a new one will be created using the config.

        :param field_name: name of the field for use in error messages
        :param annotation: a type hint such as `str` or `Annotated[str, Field(..., min_length=5)]`
        :param value: the field's assigned value
        :param config: the model's config object
        :return: the FieldInfo contained in the `annotation`, the value, or a new one from the config.
        """
        field_info_from_config = config.get_field_info(field_name)

        field_info = None
        if get_origin(annotation) is Annotated:
            field_infos = [arg for arg in get_args(annotation)[1:] if isinstance(arg, FieldInfo)]
            if len(field_infos) > 1:
                raise ValueError(f'cannot specify multiple `Annotated` `Field`s for {field_name!r}')
            field_info = next(iter(field_infos), None)
            if field_info is not None:
                field_info = copy.copy(field_info)
                field_info.update_from_config(field_info_from_config)
                if field_info.default not in (Undefined, Required):
                    raise ValueError(f'`Field` default cannot be set in `Annotated` for {field_name!r}')
                if value is not Undefined and value is not Required:
                    # check also `Required` because of `validate_arguments` that sets `...` as default value
                    field_info.default = value

        if isinstance(value, FieldInfo):
            if field_info is not None:
                raise ValueError(f'cannot specify `Annotated` and value `Field`s together for {field_name!r}')
            field_info = value
            field_info.update_from_config(field_info_from_config)
        elif field_info is None:
            field_info = FieldInfo(value, **field_info_from_config)
        value = None if field_info.default_factory is not None else field_info.default

View on GitHub (pinned to 2e5f0e2b42)

Solutions

  1. Merge the constraints into a single Field inside the Annotated: Annotated[str, Field(min_length=1, max_length=10)].
  2. Move one set of constraints into the model's Config.fields if applicable.

Example fix

// before
name: Annotated[str, Field(min_length=1), Field(max_length=10)]

# after
name: Annotated[str, Field(min_length=1, max_length=10)]
Defensive patterns

Strategy: validation

Validate before calling

from typing import get_args, get_origin, Annotated
from pydantic.v1.fields import FieldInfo

def _check_single_annotated_field(annotation):
    if get_origin(annotation) is Annotated:
        infos = [a for a in get_args(annotation)[1:] if isinstance(a, FieldInfo)]
        if len(infos) > 1:
            raise ValueError('merge multiple Annotated Field() calls into one')

Type guard

from typing import get_args, get_origin, Annotated
from pydantic.v1.fields import FieldInfo

def has_single_annotated_field(annotation) -> bool:
    if get_origin(annotation) is not Annotated:
        return True
    return sum(1 for a in get_args(annotation)[1:] if isinstance(a, FieldInfo)) <= 1

Prevention

When it happens

Trigger: Writing Annotated[str, Field(min_length=1), Field(max_length=10)] — two FieldInfo objects in one Annotated. Triggered at model creation when the annotation is processed.

Common situations: Combining constraints from reusable Annotated type aliases by stacking Field(); refactoring that accidentally duplicates Field metadata.

Related errors


AI-assisted analysis of pydantic/pydantic@2e5f0e2b42 (2026-08-04). Data as JSON: /data/errors/881ab16693db9261.json. Report an issue: GitHub.