Fix flattening of query/header/cookie param models with sibling params by maksimzayats · Pull Request #15130 · fastapi/fastapi

Summary

Fix Pydantic query/header/cookie models so they still flatten when there are sibling params in the same location.

Problem

FastAPI only flattened these models when they were the only param there:

  • Annotated[MyModel, Query()]
  • Annotated[MyModel, Header()]
  • Annotated[MyModel, Cookie()]

If you added a sibling param like extra: Query() or extra: Header(), the model stopped flattening. That broke request parsing, validation errors, and OpenAPI docs.

Fix

Model-backed query/header/cookie params now flatten consistently, even with sibling params.

This keeps existing behavior for the single-model case and preserves:

  • aliases / validation aliases
  • list handling
  • header underscore conversion
  • body embedding behavior

Old vs New

Before:

def read_items(
    m: Annotated[Filters, Query()],
    extra: Annotated[int, Query()],
)

FastAPI could treat m like one query param instead of flattening it into limit and q.

After:

  • limit, q, and extra are all handled as separate query params
  • validation errors point to the individual fields
  • OpenAPI shows flattened params, not m

Same fix applies to Header() and Cookie().