tiangolo/fastapi · error · HTTPException

Owner error

Error message

Owner error: {e}

What it means

Raised (400) inside the get_username yield-dependency's except block. The endpoint get_item raises OwnerError(username) (a custom Exception) when the item's owner != the yielded username ('Rick'). FastAPI catches exceptions thrown during a yield-dependency's cleanup and lets the dependency re-raise them as HTTPException. detail is an f-string embedding the exception message, so it reads 'Owner error: Rick'.

Solutions

  1. Request an item owned by the yielded user: GET /items/portal-gun (owner 'Rick') instead of /items/plumbus.
  2. Move the ownership check into the dependency itself (pre-yield) so authorization fails before the endpoint runs.
  3. Avoid interpolating raw exception messages into user-visible detail to prevent information leakage.

Example fix

// before
GET /items/plumbus   (owner Morty, user Rick -> OwnerError)
// after
GET /items/portal-gun (owner Rick, user Rick -> 200)
Defensive patterns

Strategy: try-catch

Validate before calling

import httpx
OWNERS = {'plumbus': 'Morty', 'portal-gun': 'Rick'}
USER = 'Rick'
def readable_for(user: str) -> list[str]:
    return [k for k, v in OWNERS.items() if v == user]
# choose an item owned by Rick
item_id = 'portal-gun'
resp = httpx.get(f'http://localhost:8000/items/{item_id}')

Type guard

def is_owned_by(item_id: object, user: str) -> bool:
    return isinstance(item_id, str) and OWNERS.get(item_id) == user

Try / catch

try:
    resp = httpx.get(f'http://localhost:8000/items/{item_id}')
    resp.raise_for_status()
except httpx.HTTPStatusError as e:
    if e.response.status_code == 400 and 'Owner error' in e.response.text:
        # access denied for this owner; pick another item or surface to user
        ...

Prevention

When it happens

Trigger: GET /items/plumbus (owner 'Morty') when the dependency yields username 'Rick'. The owner mismatch at line 30 raises OwnerError('Rick'), which propagates into the dependency's except block and becomes a 400.

Common situations: Developers misuse yield-dependencies for authorization: the check happens in the endpoint, but the HTTPException is raised in the dependency, which is confusing. Also, because the f-string interpolates arbitrary exception text, it can leak internal identifiers if OwnerError is raised with sensitive data.

Related errors


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

Appendix: source

Thrown at docs_src/dependencies/tutorial008b_an_py310.py:22

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