FastAPI "RequestValidationError" / pydantic 422 on request body in CI
FastAPI validates request bodies against the endpoint's pydantic model and returns 422 with a RequestValidationError when they do not match. A test that posts a payload the model rejects (missing field, wrong type) fails on the status code.
What this error means
A TestClient call asserts 200 but gets 422, with a body listing pydantic validation errors like "field required" or "Input should be a valid integer."
assert response.status_code == 200
E assert 422 == 200
# body:
{"detail":[{"type":"missing","loc":["body","email"],"msg":"Field required"}]}Common causes
The test payload omits a required field
The pydantic model marks a field required, but the test body does not include it, so validation fails with "Field required".
A type mismatch between payload and model
The body sends a string where the model expects an int (or similar), so pydantic rejects it before the handler runs.
How to fix it
Match the payload to the model
- Read the 422
detailto see which field and rule failed. - Build the test body from the same pydantic model to stay in sync.
- Assert on the validation detail when you are testing the 422 path deliberately.
from app.schemas import UserCreate
payload = UserCreate(email="a@b.com", age=30).model_dump()
r = client.post("/users", json=payload)
assert r.status_code == 201Test the failure path explicitly
When the 422 is expected, assert the status and the error type instead of a 200.
r = client.post("/users", json={})
assert r.status_code == 422
assert r.json()["detail"][0]["type"] == "missing"How to prevent it
- Build request payloads from the same pydantic schema the endpoint uses.
- Keep test fixtures updated when a model adds required fields.
- Assert on validation detail for negative-path tests.