{"record":{"id":"c1ba9d0c33c8a518","repo":"tiangolo/fastapi","slug":"item-not-found-there-s-only-a-plumbus-here","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/tutorial008c_an_py310.py","lineNumber":26,"sourceCode":"class InternalError(Exception):\n    pass\n\n\ndef get_username():\n    try:\n        yield \"Rick\"\n    except InternalError:\n        print(\"Oops, we didn't raise again, Britney 😱\")\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":8,"sourceCodeEnd":30,"githubUrl":"https://github.com/tiangolo/fastapi/blob/3e8d1526d83a90aaf7d6eb6dc682bf150f180b25/docs_src/dependencies/tutorial008c_an_py310.py#L8-L30","documentation":"HTTPException (404) raised in the path operation of the Annotated-typed tutorial008c. The endpoint only accepts 'plumbus' as a valid item; any other id (except 'portal-gun', which raises InternalError) yields this 404. It demonstrates that an exception swallowed in a yield-dependency's except block (here it prints and does not re-raise) does not affect the path operation's own HTTPException flow.","triggerScenarios":"GET /items/{item_id} where item_id is any value other than 'plumbus' (and other than 'portal-gun'). For example GET /items/foo or GET /items/123 returns 404.","commonSituations":"Whitelisted resource endpoints where only a fixed set of ids are valid. Developers hit this when the InternalError path (portal-gun) is swallowed by the dependency and they expect a 500, but instead get a 404 for ordinary unknown ids.","solutions":["Request GET /items/plumbus to get a successful response.","If you expected 'portal-gun' to succeed, note that id triggers InternalError which the dependency intentionally swallows (prints, does not re-raise) — see tutorial008d for the re-raise variant.","Adjust the endpoint's allowed set if new ids should be valid."],"exampleFix":"// before\nif item_id != \"plumbus\":\n    raise HTTPException(status_code=404, detail=\"Item not found, there's only a plumbus here\")\n// after (data-driven allowed set)\nALLOWED = {\"plumbus\"}\nif item_id not in ALLOWED:\n    raise HTTPException(status_code=404, detail=f\"Item not found, available: {sorted(ALLOWED)}\")","handlingStrategy":"validation","validationCode":"ALLOWED = {'plumbus'}\nif item_id not in ALLOWED:\n    print('will return 404; only plumbus is valid')","typeGuard":"def is_known_item(item_id: str) -> bool:\n    return item_id == 'plumbus'","tryCatchPattern":"import requests\nresp = requests.get(f'http://localhost:8000/items/{item_id}')\nif resp.status_code == 404:\n    print('Only plumbus is served here')","preventionTips":["Remember 'portal-gun' raises InternalError that the dependency swallows.","Treat the allowed set as configuration, not hard-coded.","Test the whitelisted id explicitly."],"tags":["fastapi","http-404","annotated","dependencies"],"backgroundTag":null,"analyzedSha":"3e8d1526d83a90aaf7d6eb6dc682bf150f180b25","analyzedAt":"2026-08-11T02:34:52.986Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}