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
- 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).
- 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.
- Make get_username resolve the real authenticated principal from a header/token rather than the hardcoded "Rick" so ownership matches expectations.
- 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
- Centralize ownership rules in a service the client consults before issuing requests.
- Document, per resource, which principal may access it.
- Treat 400 'Owner error' as authorization denial and stop retrying the same id.
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
- Owner error: {e}
- {username}
- Owner error: {e}
- Item not found, there's only a plumbus here
- Item not found, there's only a plumbus here
AI-assisted analysis of tiangolo/fastapi@42a41db11f (2026-08-04).
Data as JSON: /data/errors/7d649d4cdf11b026.json.
Report an issue: GitHub.