tiangolo/fastapi · error · HTTPException

Owner error: {e}

Error message

Owner error: {e}

What it means

This is the HTTP 400 response that FastAPI returns to the client after the yield-based `get_username` dependency catches the OwnerError raised downstream in the path operation. The detail string interpolates the exception (`f"Owner error: {e}"`), surfacing whatever the OwnerError carried (here, the username). It illustrates how yield dependencies can translate internal exceptions into structured HTTP errors at the cleanup boundary.

Source

Thrown at docs_src/dependencies/tutorial008b_py310.py:20

app = FastAPI()


data = {
    "plumbus": {"description": "Freshly pickled plumbus", "owner": "Morty"},
    "portal-gun": {"description": "Gun to create portals", "owner": "Rick"},
}


class OwnerError(Exception):
    pass


def get_username():
    try:
        yield "Rick"
    except OwnerError as e:
        raise HTTPException(status_code=400, detail=f"Owner error: {e}")


@app.get("/items/{item_id}")
def get_item(item_id: str, username: str = Depends(get_username)):
    if item_id not in data:
        raise HTTPException(status_code=404, detail="Item not found")
    item = data[item_id]
    if item["owner"] != username:
        raise OwnerError(username)
    return item

View on GitHub (pinned to 42a41db11f)

Solutions

  1. Call the endpoint with credentials/items whose owner matches the dependency-yielded username.
  2. Refine the detail to avoid leaking usernames: use a generic "Not authorized" message mapped to HTTP 403.
  3. Ensure OwnerError is the only exception type swallowed by the dependency so unrelated errors are not masked.
  4. Write a test that posts an unauthorized item_id and asserts the 400 payload shape.

Example fix

# before
except OwnerError as e:
    raise HTTPException(status_code=400, detail=f"Owner error: {e}")

# after
except OwnerError:
    raise HTTPException(status_code=403, detail="Not authorized")
Defensive patterns

Strategy: try-catch

Validate before calling

# Resolve the effective username before the call and skip items not owned by it
if item_owner != effective_username:
    raise PermissionError(f"{effective_username} cannot read this item")

Type guard

def owner_matches(item: dict, username: str) -> bool:
    return isinstance(item, dict) and item.get("owner") == username

Try / catch

try:
    resp = client.get(f"/items/{item_id}")
except httpx.HTTPStatusError:
    ...
else:
    if resp.status_code == 400 and "Owner error" in resp.text:
        # surface an authorization prompt instead of retrying
        ...

Prevention

When it happens

Trigger: Any request to GET /items/{item_id} where item_id resolves to an item whose owner differs from "Rick" (e.g. "plumbus" owner="Morty"); the handler raises OwnerError, which the dependency catches and re-raises as HTTPException(400).

Common situations: Ownership/authorization mismatch surfaced to clients; leaking internal principal names in detail strings; relying on a dependency to centralize error translation but forgetting it only fires for the specific exception type caught.

Related errors


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