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:
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:
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:
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:
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
- Is this the expected behavior? The inconsistency makes it difficult to reason about list constraints.
max_lengthis always checked first, whilemin_lengthsometimes defers to inner validations. Shouldn't both constraints be applied consistently before validating inner elements? - 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: unknownSource: pydantic/pydantic