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

HTTPException (404) in tutorial008d_an_py310 — the Annotated variant where the yield-dependency DOES re-raise InternalError. For any item_id other than 'plumbus' (and other than 'portal-gun' which raises InternalError that now propagates as a 500), the endpoint returns this 404. Demonstrates the contrast with the swallowing variant.

Solutions

  1. Request GET /items/plumbus for a success.
  2. Distinguish the two failure paths: unknown id -> 404, 'portal-gun' -> 500 InternalError (re-raised by the dependency).
  3. If you need 'portal-gun' to return a real HTTP status, convert InternalError to an HTTPException in the dependency's except block.

Example fix

// before
def get_username():
    try:
        yield "Rick"
    except InternalError:
        print("We don't swallow the internal error here, we raise again")
        raise
// after (translate to HTTP)
except InternalError as e:
    raise HTTPException(status_code=403, detail=str(e))
Defensive patterns

Strategy: try-catch

Validate before calling

ALLOWED = {'plumbus'}
if item_id not in ALLOWED:
    print('404 expected; portal-gun yields 500')

Type guard

def is_known_item(item_id: str) -> bool:
    return item_id == 'plumbus'

Try / catch

resp = requests.get(f'http://localhost:8000/items/{item_id}')
if resp.status_code == 404:
    print('unknown id')
elif resp.status_code == 500:
    print('InternalError re-raised by dependency')

Prevention

When it happens

Trigger: GET /items/{item_id} where item_id != 'plumbus' and != 'portal-gun'. GET /items/portal-gun now surfaces as InternalError (500) instead of being swallowed.

Common situations: Endpoints that both return clean 404s for unknown ids and propagate internal errors. Developers hit the 404 when testing ordinary unknown ids and a 500 when testing 'portal-gun'.

Related errors


AI-assisted analysis of tiangolo/fastapi@3e8d1526d8 (2026-08-11). Data as JSON: /api/errors/9dfeb69b8466c4c6. Report an issue: GitHub.

Appendix: 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 3e8d1526d8)