tiangolo/fastapi · error · HTTPException
Item not found, there's only a plumbus here
Error message
Item not found, there's only a plumbus here
What it means
FastAPI returns HTTP 404 with the whimsical detail "Item not found, there's only a plumbus here" when `item_id` is anything other than "plumbus" or "portal-gun". The "portal-gun" branch raises InternalError instead (handled by the yield dependency), so this 404 only fires for genuinely unknown ids. It demonstrates custom 404 messaging combined with yield-dependency exception swallowing.
Source
Thrown at docs_src/dependencies/tutorial008c_an_py310.py:26
class InternalError(Exception):
pass
def get_username():
try:
yield "Rick"
except InternalError:
print("Oops, we didn't raise again, Britney 😱")
@app.get("/items/{item_id}")
def get_item(item_id: str, username: Annotated[str, Depends(get_username)]):
if item_id == "portal-gun":
raise InternalError(
f"The portal gun is too dangerous to be owned by {username}"
)
if item_id != "plumbus":
raise HTTPException(
status_code=404, detail="Item not found, there's only a plumbus here"
)
return item_id
View on GitHub (pinned to 42a41db11f)
Solutions
- Request GET /items/plumbus (the only valid non-portal-gun id).
- If extending the API, enumerate allowed ids and document them in the OpenAPI summary.
- Normalize custom 404 detail strings across endpoints for consistency.
- Add a test asserting both the portal-gun InternalError path and the generic 404 path.
Example fix
# before
if item_id != "plumbus":
raise HTTPException(status_code=404, detail="Item not found, there's only a plumbus here")
# after
ALLOWED = {"plumbus"}
if item_id not in ALLOWED:
raise HTTPException(status_code=404, detail=f"Item '{item_id}' not found") Defensive patterns
Strategy: validation
Validate before calling
ALLOWED = {"plumbus", "portal-gun"}
if item_id not in ALLOWED:
raise ValueError(f"Item '{item_id}' not supported; only {ALLOWED}") Type guard
def is_known_item(item_id: str) -> bool:
return item_id in {"plumbus", "portal-gun"} Try / catch
r = client.get(f"/items/{item_id}")
if r.status_code == 404:
# inform the user that only plumbus/portal-gun exist
... Prevention
- Document the allowed id set in the client.
- Avoid probing random ids.
- Cache the supported list and refresh on schema changes.
When it happens
Trigger: GET /items/<anything-except-plumbus-or-portal-gun> (e.g. /items/flerb).
Common situations: Clients probing for resources that were never modeled; renaming the allowed id set without updating clients; tutorials copied with a different allowed-item list.
Related errors
- Item not found, there's only a plumbus here
- Item not found
- Item not found, there's only a plumbus here
- Item not found, there's only a plumbus here
- {username}
AI-assisted analysis of tiangolo/fastapi@42a41db11f (2026-08-04).
Data as JSON: /data/errors/c1ba9d0c33c8a518.json.
Report an issue: GitHub.