tiangolo/fastapi · error · HTTPException
Not authorized
Error message
Not authorized
What it means
Same HTTPException(403) 'Not authorized' as error 30 but in tutorial014_an_py310, which additionally calls session.close() after the not-found check. The dependency closes the session and then raises; the streaming generator then runs without an open session. Same trigger: a user_id with no matching User row.
Solutions
- Provide a user_id that exists in the User table.
- Verify the DB connection and that the table is seeded.
- If session.close() causes issues downstream (e.g. lazy access in the stream), refactor to manage the session lifecycle explicitly around the stream.
Example fix
// before
user = session.get(User, user_id)
if not user:
raise HTTPException(status_code=403, detail="Not authorized")
session.close()
// after
user = session.get(User, user_id)
if not user:
raise HTTPException(status_code=404, detail="User not found")
session.close() Defensive patterns
Strategy: validation
Validate before calling
with Session(engine) as s:
assert s.get(User, user_id) is not None, 'user missing -> 403' Type guard
def user_exists(session, user_id: int) -> bool:
return session.get(User, user_id) is not None Try / catch
resp = requests.get('http://localhost:8000/generate', params={'query': q, 'user_id': uid})
if resp.status_code == 403:
print('Not authorized (user missing)') Prevention
- Ensure user rows are seeded.
- Avoid lazy DB access after session.close() in the stream.
- Use 404 for not-found to avoid conflating with authorization.
When it happens
Trigger: GET /generate?query=...&user_id=<id> where the User row does not exist. The session is explicitly closed before the HTTPException is raised.
Common situations: Streaming endpoints where the session must be closed early to avoid holding a DB connection during a long stream. Developers hit the 403 when the user_id is wrong/absent, or when closing the session breaks later lazy loads.
Related errors
- Not authorized
- Cannot set both 'data' and 'raw_data' on the same…
- Hero not found
- Hero not found
- Hero not found
AI-assisted analysis of tiangolo/fastapi@3e8d1526d8 (2026-08-11).
Data as JSON: /api/errors/58795996f2171dd9.
Report an issue: GitHub.
Appendix: source
Thrown at docs_src/dependencies/tutorial014_an_py310.py:27
class User(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
name: str
app = FastAPI()
def get_session():
with Session(engine) as session:
yield session
def get_user(user_id: int, session: Annotated[Session, Depends(get_session)]):
user = session.get(User, user_id)
if not user:
raise HTTPException(status_code=403, detail="Not authorized")
session.close()
def generate_stream(query: str):
for ch in query:
yield ch
time.sleep(0.1)
@app.get("/generate", dependencies=[Depends(get_user)])
def generate(query: str):
return StreamingResponse(content=generate_stream(query))
View on GitHub (pinned to 3e8d1526d8)