tiangolo/fastapi · error · HTTPException
Item not found
Error message
Item not found
What it means
Raised by GET /items/{item_id} after auth passes, when the requested item_id is not a key in the in-memory fake_db dict (which only contains "foo" and "bar"). FastAPI returns HTTP 404 with detail "Item not found". This is the standard resource-not-found response for a lookup miss.
Source
Thrown at docs_src/app_testing/app_b_an_py310/main.py:27
"foo": {"id": "foo", "title": "Foo", "description": "There goes my hero"},
"bar": {"id": "bar", "title": "Bar", "description": "The bartenders"},
}
app = FastAPI()
class Item(BaseModel):
id: str
title: str
description: str | None = None
@app.get("/items/{item_id}", response_model=Item)
async def read_main(item_id: str, x_token: Annotated[str, Header()]):
if x_token != fake_secret_token:
raise HTTPException(status_code=400, detail="Invalid X-Token header")
if item_id not in fake_db:
raise HTTPException(status_code=404, detail="Item not found")
return fake_db[item_id]
@app.post("/items/")
async def create_item(item: Item, x_token: Annotated[str, Header()]) -> Item:
if x_token != fake_secret_token:
raise HTTPException(status_code=400, detail="Invalid X-Token header")
if item.id in fake_db:
raise HTTPException(status_code=409, detail="Item already exists")
fake_db[item.id] = item.model_dump()
return item
View on GitHub (pinned to 42a41db11f)
Solutions
- Use a known id ("foo" or "bar") or create the item first via POST /items/.
- Check the 404 response and surface a user-facing "not found" message rather than retrying blindly.
- Confirm item_id casing and that no leading/trailing whitespace was added.
Example fix
# before
client.get("/items/missing", headers={"X-Token":"coneofsilence"})
# after
client.post("/items/", json={"id":"missing","title":"Missing"}, headers={"X-Token":"coneofsilence"}) Defensive patterns
Strategy: validation
Validate before calling
# List valid ids before requesting
valid_ids = {"foo", "bar"}
if item_id in valid_ids:
client.get(f"/items/{item_id}", headers=auth) Type guard
def item_exists(item_id: str, known: set[str]) -> bool:
return item_id in known Try / catch
resp = client.get(f"/items/{item_id}", headers=auth)
if resp.status_code == 404:
# item does not exist; handle gracefully
... Prevention
- Discover ids via a list endpoint before fetching.
- Normalize ids (strip whitespace) before use.
- Treat 404 as a normal control-flow outcome, not a crash.
When it happens
Trigger: GET /items/{item_id} with a valid X-Token but an item_id not present in fake_db, e.g. /items/missing or /items/123.
Common situations: Requesting an item that was never created; a typo in the id; requesting an item that was deleted; using an id from a different environment's database.
Related errors
AI-assisted analysis of tiangolo/fastapi@42a41db11f (2026-08-04).
Data as JSON: /data/errors/bfc9962b922f5972.json.
Report an issue: GitHub.