tiangolo/fastapi · warning · HTTPException

Nope! I don't like 3.

Error message

Nope! I don't like 3.

What it means

HTTPException(418) raised in the path operation when item_id == 3. The tutorial overrides the default StarletteHTTPException and RequestValidationError handlers to return PlainTextResponse. This demonstrates a path-operation-driven 418 that flows through a custom http_exception_handler.

Solutions

  1. Request GET /items/{n} with n != 3 (e.g. /items/1) to succeed.
  2. If 418 is meant as a real error, switch to a conventional status (400/409).
  3. Confirm the response parser handles text/plain since the custom handler returns PlainTextResponse.

Example fix

// before
if item_id == 3:
    raise HTTPException(status_code=418, detail="Nope! I don't like 3.")
// after
if item_id == 3:
    raise HTTPException(status_code=400, detail="Value 3 is not allowed")
Defensive patterns

Strategy: validation

Validate before calling

if item_id == 3:
    print('will return 418')
# ensure item_id is an int to avoid 422
assert isinstance(item_id, int)

Type guard

def is_allowed_item(item_id: int) -> bool:
    return item_id != 3

Try / catch

resp = requests.get(f'http://localhost:8000/items/{item_id}')
if resp.status_code == 418:
    print('rejected value:', resp.text)

Prevention

When it happens

Trigger: GET /items/3. Any integer other than 3 returns 200; non-integer values return 400 (validation) via the custom validation handler.

Common situations: Path operations that reject specific inputs with non-standard status codes. Developers hit 418 when the path param equals the sentinel value 3, and may be surprised that the body is plain text (per the custom handler) rather than JSON.

Related errors


AI-assisted analysis of tiangolo/fastapi@3e8d1526d8 (2026-08-11). Data as JSON: /api/errors/267725dbdeb66756. Report an issue: GitHub.

Appendix: source

Thrown at docs_src/handling_errors/tutorial004_py310.py:25


@app.exception_handler(StarletteHTTPException)
async def http_exception_handler(request, exc):
    return PlainTextResponse(str(exc.detail), status_code=exc.status_code)


@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc: RequestValidationError):
    message = "Validation errors:"
    for error in exc.errors():
        message += f"\nField: {error['loc']}, Error: {error['msg']}"
    return PlainTextResponse(message, status_code=400)


@app.get("/items/{item_id}")
async def read_item(item_id: int):
    if item_id == 3:
        raise HTTPException(status_code=418, detail="Nope! I don't like 3.")
    return {"item_id": item_id}

View on GitHub (pinned to 3e8d1526d8)