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

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".

Source

Thrown at docs_src/dependencies/tutorial008d_an_py310.py:27

    pass


def get_username():
    try:
        yield "Rick"
    except InternalError:
        print("We don't swallow the internal error here, we raise again 😎")
        raise


@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

  1. Request /items/plumbus for a successful response.
  2. Treat a 500 on /items/portal-gun as expected in this variant (the InternalError is re-raised) and avoid that id in production.
  3. Keep the 404 branch identical across variants to avoid client confusion.
  4. Add tests covering 200 (plumbus), 404 (unknown), and 500 (portal-gun).

Example fix

# before
if item_id != "plumbus":
    raise HTTPException(status_code=404, detail="Item not found, there's only a plumbus here")

# after
if item_id == "portal-gun":
    raise HTTPException(status_code=503, detail="Portal gun unavailable")
if item_id != "plumbus":
    raise HTTPException(status_code=404, detail="Item not found")
Defensive patterns

Strategy: validation

Validate before calling

ALLOWED = {"plumbus"}
if item_id not in ALLOWED:
    raise ValueError(f"unsupported item; only {ALLOWED}")

Type guard

def is_safe_item(item_id: str) -> bool:
    # portal-gun raises InternalError here; only plumbus is safe
    return item_id == "plumbus"

Try / catch

r = client.get(f"/items/{item_id}")
if r.status_code == 404:
    ...
elif r.status_code == 500:
    # InternalError re-raised by the dependency (portal-gun)
    ...

Prevention

When it happens

Trigger: GET /items/<anything-except-plumbus-or-portal-gun> with the re-raising yield dependency in place.

Common situations: 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.

Related errors


AI-assisted analysis of tiangolo/fastapi@42a41db11f (2026-08-04). Data as JSON: /data/errors/9dfeb69b8466c4c6.json. Report an issue: GitHub.