tiangolo/fastapi · error · HTTPException
{"errors": exc.errors(), "body": body.decode()}
Error message
{"errors": exc.errors(), "body": body.decode()} What it means
Legacy-style (default-parameter) variant of error 12: the same ValidationErrorLoggingRoute intercepts RequestValidationError on POST / and raises HTTPException(422) with detail {'errors': exc.errors(), 'body': <decoded raw body>}. Identical behavior; only the route signature style differs (numbers: list[int] = Body() vs Annotated).
Solutions
- Send a valid JSON array of ints with Content-Type: application/json.
- Pre-check the payload client-side.
- Use the Annotated variant for forward compatibility.
Example fix
// before POST / body: 5 // after POST / body: [1,2,3]
Defensive patterns
Strategy: validation
Validate before calling
import json, httpx
def is_int_list(body: str) -> bool:
try:
parsed = json.loads(body)
except json.JSONDecodeError:
return False
return isinstance(parsed, list) and all(isinstance(x, int) for x in parsed)
payload = '[1,2,3]'
if is_int_list(payload):
resp = httpx.post('http://localhost:8000/', content=payload, headers={'Content-Type': 'application/json'}) Type guard
def is_list_of_int(value: object) -> bool:
return isinstance(value, list) and all(isinstance(x, int) and not isinstance(x, bool) for x in value) Try / catch
try:
resp = httpx.post(url, content=payload, headers={'Content-Type': 'application/json'})
resp.raise_for_status()
except httpx.HTTPStatusError as e:
if e.response.status_code == 422:
detail = e.response.json()
... Prevention
- Send a JSON array of ints with the correct content type.
- Pre-validate client-side.
- Note the custom 422 body shape differs from FastAPI's default.
When it happens
Trigger: POST / with a body that fails to parse as list[int]. The custom handler returns the errors plus the raw submitted body.
Common situations: Malformed JSON, sending a scalar instead of a list, wrong content-type, or relying on the default FastAPI 422 shape while this route echoes the body.
Related errors
- {"errors": exc.errors(), "body": body.decode()}
- Expected UploadFile, received
- Invalid YAML
- validation error(s)
- Cannot set both 'data' and 'raw_data' on the same…
AI-assisted analysis of tiangolo/fastapi@3e8d1526d8 (2026-08-11).
Data as JSON: /api/errors/6a8554dbe71908b3.
Report an issue: GitHub.
Appendix: source
Thrown at docs_src/custom_request_and_route/tutorial002_py310.py:18
from collections.abc import Callable
from fastapi import Body, FastAPI, HTTPException, Request, Response
from fastapi.exceptions import RequestValidationError
from fastapi.routing import APIRoute
class ValidationErrorLoggingRoute(APIRoute):
def get_route_handler(self) -> Callable:
original_route_handler = super().get_route_handler()
async def custom_route_handler(request: Request) -> Response:
try:
return await original_route_handler(request)
except RequestValidationError as exc:
body = await request.body()
detail = {"errors": exc.errors(), "body": body.decode()}
raise HTTPException(status_code=422, detail=detail)
return custom_route_handler
app = FastAPI()
app.router.route_class = ValidationErrorLoggingRoute
@app.post("/")
async def sum_numbers(numbers: list[int] = Body()):
return sum(numbers)
View on GitHub (pinned to 3e8d1526d8)