422 Unprocessable Entity: {"detail":[{"type":"missing","loc":["body"],"msg":"Field required"}]}
ID: python/fastapi-422-validation-error
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| 311 | active | — | — | — |
Root Cause
Almost always a content-type mismatch between client and server, or a Pydantic v1-to-v2 migration issue where validators silently stopped working. The 422 response includes detailed field-level error information.
genericWorkarounds
-
93% success Verify Content-Type header matches the endpoint parameter type
Use application/json for Body/BaseModel parameters, application/x-www-form-urlencoded for Form() fields. Check the client is sending the right Content-Type. In curl: -H 'Content-Type: application/json' -d '{"field": "value"}'. With Form() fields, use -d 'field=value' (no JSON). -
87% success Update Pydantic v1 validators to v2 syntax
For FastAPI >=0.100 with Pydantic v2: change @validator to @field_validator, change class Config to model_config = ConfigDict(...), change orm_mode=True to from_attributes=True. Pydantic v2 silently ignores v1-style validators.
-
85% success Use Body(embed=True) for single-field JSON bodies
FastAPI expects {"field": value} for models, but single-parameter endpoints may receive just the value. Add Body(embed=True) to force wrapping: async def endpoint(item: str = Body(embed=True)).Sources: https://fastapi.tiangolo.com/tutorial/body-multiple-params/
Dead Ends
Common approaches that don't work:
-
Adding Optional to the field type to make it not required
68% fail
If the client is sending data in the wrong Content-Type (e.g., form data instead of JSON), the field is 'missing' from the JSON body even though it was sent. Making the field Optional masks the root cause and allows None values through validation.
-
Switching from Pydantic BaseModel to plain dict parameter
80% fail
Loses all validation and type safety. The error shifts downstream to application logic where it is harder to debug. The 422 is actually helpful — it tells you exactly what is wrong with the request.
-
Adding response_model_exclude_unset=True to the endpoint
95% fail
response_model_exclude_unset controls response serialization, not request validation. It has zero effect on incoming 422 errors.