tiangolo/fastapi · error · ResponseValidationError
{n} validation error(s): {errors}
Error message
{n} validation error(s):
{errors} What it means
ResponseValidationError raised by serialize_response (routing.py:324) when validating the endpoint's return value against the declared response_model field. The shared message comes from ValidationException.__str__ ('{n} validation error(s):\n{errors}'); errors are the pydantic validation errors produced by field.validate(response_content, ..., loc=("response",)). It surfaces as an HTTP 500 because the response the code produced does not match the response_model contract.
Source
Thrown at fastapi/routing.py:324
exclude: IncEx | None = None,
by_alias: bool = True,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
is_coroutine: bool = True,
endpoint_ctx: EndpointContext | None = None,
dump_json: bool = False,
) -> Any:
if field:
if is_coroutine:
value, errors = field.validate(response_content, {}, loc=("response",))
else:
value, errors = await run_in_threadpool(
field.validate, response_content, {}, loc=("response",)
)
if errors:
ctx = endpoint_ctx or EndpointContext()
raise ResponseValidationError(
errors=errors,
body=response_content,
endpoint_ctx=ctx,
)
serializer = field.serialize_json if dump_json else field.serialize
return serializer(
value,
include=include,
exclude=exclude,
by_alias=by_alias,
exclude_unset=exclude_unset,
exclude_defaults=exclude_defaults,
exclude_none=exclude_none,
)
else:
return jsonable_encoder(response_content)
View on GitHub (pinned to 3e8d1526d8)
Solutions
- Make the endpoint return data that matches response_model (correct types, required fields present).
- Loosen the response_model where appropriate: Optional fields, Union, or response_model_exclude_none.
- Convert ORM objects with from_attributes=True (model_config) or build the response model explicitly.
- Reproduce under TestClient and read the per-field errors in the 500 response body to fix the mismatch.
Example fix
// before
class HeroOut(BaseModel):
id: int
name: str
age: int # required
@app.get("/heroes/{i}", response_model=HeroOut)
def read(i: int):
return {"id": i, "name": "x"} # missing age -> ResponseValidationError
// after
class HeroOut(BaseModel):
id: int
name: str
age: int | None = None
@app.get("/heroes/{i}", response_model=HeroOut)
def read(i: int):
return {"id": i, "name": "x"} Defensive patterns
Strategy: validation
Validate before calling
# Validate the endpoint return against response_model in a unit test
from fastapi.testclient import TestClient
from app import app, HeroOut
def test_read_hero_matches_response_model():
client = TestClient(app)
r = client.get("/heroes/1")
assert r.status_code == 200
HeroOut.model_validate(r.json()) # raises if shape mismatches response_model Try / catch
from fastapi.exceptions import ResponseValidationError
from fastapi.testclient import TestClient
client = TestClient(app, raise_server_exceptions=False)
r = client.get("/heroes/1")
if r.status_code == 500 and "validation error" in r.text:
# inspect r.json()['detail'] for the failing response fields
print(r.text) Prevention
- Keep response_model and the endpoint return in lockstep; update both together.
- Use Optional/Union fields where data can legitimately be absent.
- Enable from_attributes on response models mapping ORM objects.
- Add TestClient tests asserting each endpoint returns a valid response_model payload.
When it happens
Trigger: An endpoint returns data that fails validation against its response_model — e.g. returning None where the model requires fields, returning an int where a str is declared, extra/missing fields with strict mode, a nested object that does not coerce to the model, or an ORM object that does not map onto the response_model.
Common situations: Changing the response_model without updating the endpoint return; returning a raw ORM row whose fields do not match the schema; a DB null landing on a required response field; stricter pydantic v2 validation after an upgrade; returning a wrong-shaped dict from a helper.
Related errors
- {"errors": exc.errors(), "body": body.decode()}
- {"errors": exc.errors(), "body": body.decode()}
- Expected UploadFile, received: {type(__input_value)}
- pydantic.v1 models are no longer supported by FastAPI. Pleas
- Invalid YAML
AI-assisted analysis of tiangolo/fastapi@3e8d1526d8 (2026-08-11).
Data as JSON: /api/errors/2dd261a1d0e75523.
Report an issue: GitHub.