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
- Allow admins to bypass the ownership check explicitly
- Return 403 without confirming whether the target id exists
- 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)