#11362·pydantic

Unexpected order of list and inner constraints validation

Author: simonwahlgrenCreated Jan 30, 2025Updated Sep 16, 2026
Labelsbug V2topic-annotations

Initial Checks

  • I confirm that I'm using Pydantic V2

Description

Hi Pydantic Team,

I'm trying to understand how list constraints are applied relative to inner constraints. Consider the following example:

python
from typing import Annotated, TypeVar
from pydantic import Field, BaseModel

T = TypeVar("T")
List = Annotated[list[T], Field(min_length=5, max_length=10)]
String = Annotated[str, Field(max_length=10)]

class TestModel(BaseModel):
    titles: Annotated[List[String], Field(max_length=20)]

Expected vs. Actual Behavior

When exceeding max_length on the list, validation happens as expected before checking the inner constraints:

python
TestModel(titles=["a" * 11] * 21)
List should have at most 20 items after validation, not 21 [type=too_long, input_value=[...], input_type=list]

However, when violating the min_length constraint, the inner constraints are validated before the list constraint:

python
TestModel(titles=["a" * 11] * 4)
titles.0  
    String should have at most 10 characters [type=string_too_long, input_value='aaaaaaaaaaa', input_type=str]
...

Only after fixing the inner string constraint does the min_length list constraint trigger:

python
TestModel(titles=["a" * 10] * 4)
List should have at least 5 items after validation, not 4 [type=too_short, input_value=[...], input_type=list]

Questions and Concerns

  1. Is this the expected behavior? The inconsistency makes it difficult to reason about list constraints. max_length is always checked first, while min_length sometimes defers to inner validations. Shouldn't both constraints be applied consistently before validating inner elements?
  2. Performance Considerations: It seems more efficient to apply list constraints before validating inner elements, especially for large nested models.

Looking forward to your thoughts!

Best regards,
Simon

Python, Pydantic & OS Version

pydantic version: 2.10.6
        pydantic-core version: 2.27.2
          pydantic-core build: profile=release pgo=false
                 install path: /home/simon/dev/lab/pydantic/.venv/lib/python3.12/site-packages/pydantic
               python version: 3.12.4 (main, Jul  9 2024, 10:49:22) [GCC 14.1.1 20240522]
                     platform: Linux-6.6.72-1-lts-x86_64-with-glibc2.40
             related packages: typing_extensions-4.12.2
                       commit: unknown