tiangolo/fastapi · warning · HTTPException
Nope! I don't like 3.
Error message
Nope! I don't like 3.
What it means
FastAPI returns HTTP 418 "I'm a Teapot" with detail "Nope! I don't like 3." when the path parameter item_id equals 3. The endpoint declares item_id: int, so non-integer input fails earlier as a 422 validation error; only the integer 3 reaches this branch. The example also overrides the default HTTP and validation exception handlers to return PlainTextResponse bodies.
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 42a41db11f)
Solutions
- Request any integer other than 3 (e.g. /items/1, /items/42).
- If you maintain the API, replace the joke 418 with a meaningful status (e.g. 400 or 409).
- Ensure clients parse text/plain bodies since the custom handler returns PlainTextResponse.
- Document reserved values in the OpenAPI description.
Example fix
# before
if item_id == 3:
raise HTTPException(status_code=418, detail="Nope! I don't like 3.")
# after
FORBIDDEN = {3}
if item_id in FORBIDDEN:
raise HTTPException(status_code=400, detail=f"item_id {item_id} is not allowed") Defensive patterns
Strategy: validation
Validate before calling
if item_id == 3:
raise ValueError("item_id 3 is rejected") Type guard
def is_allowed_item_id(item_id: int) -> bool:
return item_id != 3 Try / catch
r = client.get(f"/items/{item_id}")
if r.status_code == 418 and "don't like 3" in r.text:
# pick a different id
... Prevention
- Avoid reserved values like 3.
- Note the response is text/plain due to the custom handler.
- Document forbidden values in the client.
When it happens
Trigger: GET /items/3 (integer three).
Common situations: Clients hard-coding forbidden values; reusing the demo value 3 in real schemas; relying on PlainTextResponse in handlers while clients expect JSON.
Related errors
- Nope! I don't like 3.
- Oops! {exc.name} did something. There goes a rainbow...
- Item not found
- Item not found
- Invalid X-Token header
AI-assisted analysis of tiangolo/fastapi@42a41db11f (2026-08-04).
Data as JSON: /data/errors/267725dbdeb66756.json.
Report an issue: GitHub.