{"id":"9dfeb69b8466c4c6","repo":"tiangolo/fastapi","slug":"item-not-found-there-s-only-a-plumbus-here-9dfeb6","errorCode":null,"errorMessage":"Item not found, there's only a plumbus here","messagePattern":"Item not found, there's only a plumbus here","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"docs_src/dependencies/tutorial008d_an_py310.py","lineNumber":27,"sourceCode":"    pass\n\n\ndef get_username():\n    try:\n        yield \"Rick\"\n    except InternalError:\n        print(\"We don't swallow the internal error here, we raise again 😎\")\n        raise\n\n\n@app.get(\"/items/{item_id}\")\ndef get_item(item_id: str, username: Annotated[str, Depends(get_username)]):\n    if item_id == \"portal-gun\":\n        raise InternalError(\n            f\"The portal gun is too dangerous to be owned by {username}\"\n        )\n    if item_id != \"plumbus\":\n        raise HTTPException(\n            status_code=404, detail=\"Item not found, there's only a plumbus here\"\n        )\n    return item_id\n","sourceCodeStart":9,"sourceCodeEnd":31,"githubUrl":"https://github.com/tiangolo/fastapi/blob/42a41db11f6882807ac3c057b942178d53b97438/docs_src/dependencies/tutorial008d_an_py310.py#L9-L31","documentation":"Same 404 \"Item not found, there's only a plumbus here\" in the tutorial008d variant, whose `get_username` dependency does NOT swallow InternalError but re-raises it. The 404 itself is unchanged: it fires only for unknown item_ids that are also not \"portal-gun\".","triggerScenarios":"GET /items/<anything-except-plumbus-or-portal-gun> with the re-raising yield dependency in place.","commonSituations":"Clients requesting unknown ids; the re-raise variant means an InternalError (portal-gun) will now propagate as HTTP 500 rather than be swallowed, so distinguishing a true 404 from the 500 path matters.","solutions":["Request /items/plumbus for a successful response.","Treat a 500 on /items/portal-gun as expected in this variant (the InternalError is re-raised) and avoid that id in production.","Keep the 404 branch identical across variants to avoid client confusion.","Add tests covering 200 (plumbus), 404 (unknown), and 500 (portal-gun)."],"exampleFix":"# before\nif item_id != \"plumbus\":\n    raise HTTPException(status_code=404, detail=\"Item not found, there's only a plumbus here\")\n\n# after\nif item_id == \"portal-gun\":\n    raise HTTPException(status_code=503, detail=\"Portal gun unavailable\")\nif item_id != \"plumbus\":\n    raise HTTPException(status_code=404, detail=\"Item not found\")","handlingStrategy":"validation","validationCode":"ALLOWED = {\"plumbus\"}\nif item_id not in ALLOWED:\n    raise ValueError(f\"unsupported item; only {ALLOWED}\")","typeGuard":"def is_safe_item(item_id: str) -> bool:\n    # portal-gun raises InternalError here; only plumbus is safe\n    return item_id == \"plumbus\"","tryCatchPattern":"r = client.get(f\"/items/{item_id}\")\nif r.status_code == 404:\n    ...\nelif r.status_code == 500:\n    # InternalError re-raised by the dependency (portal-gun)\n    ...","preventionTips":["Avoid 'portal-gun' on this variant since the dependency re-raises.","Distinguish 404 (unknown) from 500 (propagated internal error).","Pin the client to known-safe ids."],"tags":["fastapi","http-404","not-found","dependencies","yield-dependency"],"analyzedSha":"42a41db11f6882807ac3c057b942178d53b97438","analyzedAt":"2026-08-04T19:23:32.007Z","schemaVersion":2}