affaan-m/ECC · error · HTTPException

Not authorized

Error message

Not authorized

What it means

Illustrative ownership check from the fastapi-patterns skill: in PATCH /users/{user_id}, the authenticated user's id does not equal the target id (and no admin override exists), so the router returns 403 before the update runs. Accessing another user's resource is the rejected action.

Solutions

  1. Allow admins to bypass the ownership check explicitly
  2. Return 403 without confirming whether the target id exists
  3. Apply the same ownership check to every user-scoped route
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at skills/fastapi-patterns/SKILL.md:276 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of affaan-m/ECC@d8409a4b08 (2026-08-26). Data as JSON: /api/errors/34c37b51d0c566a9. Report an issue: GitHub.

Appendix: source

Thrown at skills/fastapi-patterns/SKILL.md:276

    db: DbDep,
    current_user: ActiveUserDep,
    skip: Annotated[int, Query(ge=0)] = 0,
    limit: Annotated[int, Query(ge=1, le=100)] = 20,
) -> UserListResponse:
    service = UserService(db)
    users, total = await service.list(skip=skip, limit=limit)
    return UserListResponse(total=total, items=users)


@router.patch("/{user_id}", response_model=UserResponse)
async def update_user(
    user_id: int,
    payload: UserUpdate,
    db: DbDep,
    current_user: ActiveUserDep,
) -> UserResponse:
    if current_user.id != user_id:
        raise HTTPException(status_code=403, detail="Not authorized")
    service = UserService(db)
    try:
        user = await service.update(user_id, payload)
    except DuplicateUserError:
        raise HTTPException(status_code=400, detail="Email already registered")
    if user is None:
        raise HTTPException(status_code=404, detail="User not found")
    return user


@router.post("/token")
async def login(
    form_data: Annotated[OAuth2PasswordRequestForm, Depends()],
    db: DbDep,
) -> dict[str, str]:
    service = UserService(db)
    token = await service.authenticate(form_data.username, form_data.password)
    if token is None:

View on GitHub (pinned to d8409a4b08)