{"id":"cf00267b1766221c","repo":"tiangolo/fastapi","slug":"item-not-found-cf0026","errorCode":null,"errorMessage":"Item not found","messagePattern":"Item not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"docs_src/dependencies/tutorial008b_py310.py","lineNumber":26,"sourceCode":"    \"portal-gun\": {\"description\": \"Gun to create portals\", \"owner\": \"Rick\"},\n}\n\n\nclass OwnerError(Exception):\n    pass\n\n\ndef get_username():\n    try:\n        yield \"Rick\"\n    except OwnerError as e:\n        raise HTTPException(status_code=400, detail=f\"Owner error: {e}\")\n\n\n@app.get(\"/items/{item_id}\")\ndef get_item(item_id: str, username: str = Depends(get_username)):\n    if item_id not in data:\n        raise HTTPException(status_code=404, detail=\"Item not found\")\n    item = data[item_id]\n    if item[\"owner\"] != username:\n        raise OwnerError(username)\n    return item\n","sourceCodeStart":8,"sourceCodeEnd":31,"githubUrl":"https://github.com/tiangolo/fastapi/blob/42a41db11f6882807ac3c057b942178d53b97438/docs_src/dependencies/tutorial008b_py310.py#L8-L31","documentation":"FastAPI returns HTTP 404 with detail \"Item not found\" when the path parameter `item_id` is not a key in the in-memory `data` dict. The check `if item_id not in data` runs before the owner comparison, so unknown resources never reach the authorization logic. It is the canonical FastAPI pattern for missing-resource responses.","triggerScenarios":"GET /items/{item_id} with an item_id that is neither \"plumbus\" nor \"portal-gun\" (e.g. /items/schmeckel).","commonSituations":"Client typos in resource ids; stale references to deleted records; switching from the toy dict to a real DB without preserving the existence check; returning 404 from a dependency that runs after other side effects.","solutions":["Request a known item_id present in `data` (\"plumbus\" or \"portal-gun\").","If wiring a real store, replace the dict membership test with a DB lookup and keep the same 404 on miss.","Log the missing id server-side for telemetry while returning the generic 404 to the client.","Add a route-level test covering the not-found case."],"exampleFix":"# before\nif item_id not in data:\n    raise HTTPException(status_code=404, detail=\"Item not found\")\n\n# after (DB-backed)\nitem = session.get(Item, item_id)\nif item is None:\n    raise HTTPException(status_code=404, detail=\"Item not found\")","handlingStrategy":"validation","validationCode":"KNOWN_ITEMS = {\"plumbus\", \"portal-gun\"}\nif item_id not in KNOWN_ITEMS:\n    raise KeyError(f\"unknown item {item_id}; valid: {KNOWN_ITEMS}\")\nclient.get(f\"/items/{item_id}\")","typeGuard":"def item_exists(item_id: str, store: dict) -> bool:\n    return item_id in store","tryCatchPattern":"r = client.get(f\"/items/{item_id}\")\nif r.status_code == 404 and r.json().get(\"detail\") == \"Item not found\":\n    # offer the user the list of valid ids\n    ...","preventionTips":["Fetch/refresh the list of valid ids before issuing reads.","Treat 404 as terminal for that id; do not retry unchanged.","Validate client-side input shape before the network call."],"tags":["fastapi","http-404","not-found","dependencies"],"analyzedSha":"42a41db11f6882807ac3c057b942178d53b97438","analyzedAt":"2026-08-04T19:23:32.007Z","schemaVersion":2}