tiangolo/fastapi · error · OwnerError

{username}

Error message

{username}

What it means

A custom OwnerError is raised inside the path operation when an item exists in the in-memory `data` store but its `owner` field does not match the username yielded by the `get_username` dependency (hard-coded to "Rick"). Because `get_username` is a yield-based dependency, FastAPI routes the exception back into the dependency's `except OwnerError` block, which converts it into HTTP 400 with detail "Owner error: <username>". The `{username}` payload is the identity that was denied access. This example demonstrates FastAPI's yield-dependency cleanup-and-exception-handling pattern.

Source

Thrown at docs_src/dependencies/tutorial008b_an_py310.py:31

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: Annotated[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. Pass credentials that match the item's owner, or request an item owned by the yielded user (e.g. "portal-gun" which is owned by Rick).
  2. If you own the code, change the owner check to return HTTP 403 with a descriptive detail instead of a bare OwnerError so clients get a stable status code.
  3. Make get_username resolve the real authenticated principal from a header/token rather than the hardcoded "Rick" so ownership matches expectations.
  4. Add an integration test asserting which item_ids each user may read.

Example fix

# before
def get_item(item_id: str, username: Annotated[str, Depends(get_username)]):
    if item["owner"] != username:
        raise OwnerError(username)

# after
if item["owner"] != username:
    raise HTTPException(status_code=403, detail=f"{username} is not the owner of {item_id}")
Defensive patterns

Strategy: validation

Validate before calling

# Before calling /items/{item_id}, ensure your principal matches the item owner
KNOWN_OWNERS = {"plumbus": "Morty", "portal-gun": "Rick"}
USERNAME = "Rick"
def can_read(item_id: str) -> bool:
    return KNOWN_OWNERS.get(item_id) == USERNAME
# only call when can_read(item_id) is True

Type guard

def is_owned_by(item_id: str, owner: str, store: dict[str, dict]) -> bool:
    item = store.get(item_id)
    return bool(item) and item.get("owner") == owner

Try / catch

import httpx
with httpx.Client(base_url="http://localhost:8000") as c:
    r = c.get(f"/items/{item_id}")
    if r.status_code == 400 and r.json().get("detail", "").startswith("Owner error:"):
        # ownership denied; pick a different item or escalate permissions
        ...

Prevention

When it happens

Trigger: GET /items/{item_id} for item_id "plumbus" (owner="Morty") with the dependency-injected username="Rick"; the owner mismatch trips `if item["owner"] != username: raise OwnerError(username)`.

Common situations: Authorization/ownership checks implemented as exceptions inside handlers wired to yield-based session/user dependencies; replacing the toy `get_username` with a real auth provider whose returned identity differs from the resource's stored owner; changing the `data` dict's owner values during refactoring without updating the dependency.

Related errors


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