tiangolo/fastapi · error · HTTPException

{"errors": exc.errors(), "body": body.decode()}

Error message

{"errors": exc.errors(), "body": body.decode()}

What it means

Identical to error 12 but in the non-Annotated variant (numbers: list[int] = Body()). The custom ValidationErrorLoggingRoute catches RequestValidationError and returns HTTP 422 with {"errors": ..., "body": ...}. Same trigger and meaning.

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 42a41db11f)

Solutions

  1. POST a JSON list of integers.
  2. Use the detail.errors[] to locate the validation failure.
  3. Pre-validate the payload client-side.

Example fix

# before
client.post("/", json="1,2,3")
# after
client.post("/", json=[1,2,3])
Defensive patterns

Strategy: try-catch

Validate before calling

payload = [1, 2, 3]
assert isinstance(payload, list) and all(isinstance(i, int) for i in payload)

Type guard

def is_int_list(body) -> bool:
    return isinstance(body, list) and all(isinstance(i, int) for i in body)

Try / catch

resp = client.post("/", json=payload)
if resp.status_code == 422:
    detail = resp.json()["detail"]
    for err in detail["errors"]:
        print(err["loc"], err["type"])

Prevention

When it happens

Trigger: POST / to the py310 variant with a body that is not a valid list[int].

Common situations: Malformed JSON, wrong schema, non-integer list elements.

Related errors


AI-assisted analysis of tiangolo/fastapi@42a41db11f (2026-08-04). Data as JSON: /data/errors/6a8554dbe71908b3.json. Report an issue: GitHub.