datawhalechina/hello-agents · warning · HTTPException
会话不存在或已过期
Error message
会话不存在或已过期
What it means
FastAPI HTTPException 404 raised by get_session_pair when a session_id is not a key in the in-memory active_sessions dict. Sessions live only in process memory — there is no persistence and no TTL, so 'expired' really means 'gone': server restart, session never created, or id typo. Multi-worker deployments (uvicorn --workers N) make this frequent because session created on worker A is invisible to worker B.
Source
Thrown at Co-creation-projects/afei-GuessWhoAmI/backend/main.py:90
)
# Configure CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Global session storage: session_id -> (GameSession, HistoricalFigureAgent)
active_sessions: Dict[str, tuple] = {}
# Helper functions
def get_session_pair(session_id: str):
"""Get game session and agent, raise exception if not found"""
if session_id not in active_sessions:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="会话不存在或已过期"
)
return active_sessions[session_id]
def create_response(success: bool, message: str, data: dict = None, error: str = None) -> GameResponse:
"""Create standardized response"""
return GameResponse(
success=success,
message=message,
data=data,
error=error
)
# API endpoints
@app.get("/")
async def root():
"""Root endpoint"""View on GitHub (pinned to 606a07d341)
Solutions
- Client should treat 404 on this endpoint as 'session lost' and transparently call /api/game/start to create a new session
- If running multiple workers, pin sessions with sticky routing or move session state to Redis
- Disable auto-reload in any long-game deployment (uvicorn --reload off)
- Verify the session_id matches the exact UUID returned by /api/game/start (no truncation, no encoding issues)
Example fix
# before (client pseudocode)
resp = post('/api/game/ask', {'session_id': sid, ...})
if resp.status_code != 200: raise
# after
resp = post('/api/game/ask', {'session_id': sid, ...})
if resp.status_code == 404 and '会话不存在' in resp.json()['detail']:
# session lost (restart / other worker) — restart the game
start = post('/api/game/start').json()
sid = start['data']['session_id']
resp = post('/api/game/ask', {'session_id': sid, ...}) Defensive patterns
Strategy: fallback
Validate before calling
# client-side: confirm session still valid before a long interaction
async def ensure_session(sid: str | None) -> str:
if sid and (await client.get(f'/api/game/state/{sid}')).status_code == 200:
return sid
start = (await client.post('/api/game/start')).json()
return start['data']['session_id'] Try / catch
from fastapi import HTTPException
try:
session, agent = get_session_pair(session_id)
except HTTPException as e:
if e.status_code == 404:
# transparent restart for the player
return create_response(False, "会话已失效,请重新开始", error="SESSION_LOST")
raise Prevention
- Client: on 404 detail '会话不存在或已过期', auto-call /api/game/start and resume
- Run a single worker or move session state to Redis if you scale out
- Disable --reload in deployments; restarts wipe in-memory sessions
When it happens
Trigger: Client calls /api/game/ask or similar with a session_id from before a server restart; typo'd or truncated UUID; calling an endpoint before POST /api/game/start; load balancer routing the second request to a different worker; long-running game where the process restarted on deploy.
Common situations: Dev server auto-reloading on file change (kills all sessions); Docker container redeploy; scaling to multiple replicas behind a load balancer; frontend keeping a stale session_id in localStorage across days.
Related errors
AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14).
Data as JSON: /api/errors/9b18ee39d4757a0d.
Report an issue: GitHub.