{"record":{"id":"495c6dc036ab8c95","repo":"abi/screenshot-to-code","slug":"session-not-found","errorCode":null,"errorMessage":"Session not found","messagePattern":"Session not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"backend/routes/eval_sets.py","lineNumber":218,"sourceCode":"async def create_eval_session(request: CreateEvalSessionRequest) -> EvalSessionModel:\n    try:\n        eval_sets.get_set(request.eval_set)\n    except eval_sets.InvalidSetNameError as e:\n        raise HTTPException(status_code=400, detail=str(e))\n    except eval_sets.EvalSetNotFoundError:\n        raise HTTPException(\n            status_code=404, detail=f\"Eval set not found: {request.eval_set}\"\n        )\n    session = eval_sessions.create_session(request.eval_set, request.name)\n    return _session_to_model(session)\n\n\n@router.post(\n    \"/eval-sessions/{session_id}/activate\", response_model=EvalSessionModel\n)\nasync def activate_eval_session(session_id: str) -> EvalSessionModel:\n    if eval_sessions.get_session(session_id) is None:\n        raise HTTPException(status_code=404, detail=\"Session not found\")\n    session = eval_sessions.activate_session(session_id)\n    assert session is not None\n    return _session_to_model(session)\n\n\ndef _is_stale_running(status: str, created_at: str) -> bool:\n    if status != \"running\":\n        return False\n    try:\n        started = datetime.fromisoformat(created_at)\n    except ValueError:\n        return True\n    return datetime.now() - started > _STALE_RUNNING_AFTER\n\n\n@router.get(\n    \"/eval-sessions/{session_id}/matrix\", response_model=SessionMatrixResponse\n)","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/abi/screenshot-to-code/blob/d026163f586dfa8c5c10d28c36edd59a9d3b0e88/backend/routes/eval_sets.py#L200-L236","documentation":"Raised by POST /eval-sessions/{session_id}/activate (404) when eval_sessions.get_session() returns None — the session id is unknown. Sessions live in the eval-sessions store; an id can become stale when the session was deleted, the store was reset, or the backend restarted with ephemeral/in-memory session storage.","triggerScenarios":"Activating a session id from an old list, after the sessions store was cleared, or with a typo'd/truncated id. The check is a simple lookup before activate_session() runs.","commonSituations":"UI holds a session id across a backend restart; sessions pruned by cleanup; concurrent activation of a since-deleted session.","solutions":["GET /eval-sessions to list current sessions and activate one of those ids.","Create a new session via POST /eval-sessions if the old one is gone.","Refresh session state after backend restarts rather than caching ids indefinitely."],"exampleFix":"# before\nrequests.post(url + f\"/eval-sessions/{sid}/activate\")  # 404\n\n# after\nsessions = requests.get(url + \"/eval-sessions\").json()[\"sessions\"]\nif not any(s[\"session_id\"] == sid for s in sessions):\n    sid = requests.post(url + \"/eval-sessions\", json={\"eval_set\": set_name}).json()[\"session_id\"]\nrequests.post(url + f\"/eval-sessions/{sid}/activate\")","handlingStrategy":"validation","validationCode":"sessions = requests.get(url + \"/eval-sessions\").json()[\"sessions\"]\nknown = {s[\"session_id\"] for s in sessions}\nif session_id not in known:\n    raise LookupError(f\"session {session_id!r} unknown; active={sessions}\")","typeGuard":"def session_exists(session_id: str, sessions: list[dict]) -> bool:\n    return any(s.get(\"session_id\") == session_id for s in sessions)","tryCatchPattern":"resp = requests.post(url + f\"/eval-sessions/{session_id}/activate\")\nif resp.status_code == 404:\n    new = requests.post(url + \"/eval-sessions\", json={\"eval_set\": set_name}).json()\n    resp = requests.post(url + f\"/eval-sessions/{new['session_id']}/activate\")\nresp.raise_for_status()","preventionTips":["Fetch GET /eval-sessions before activating; don't cache session ids across restarts.","On 404, recreate the session rather than retrying the same id.","Refresh UI session lists after backend restarts or cleanups."],"tags":["fastapi","http-404","eval-sessions","lifecycle","state"],"backgroundTag":null,"analyzedSha":"d026163f586dfa8c5c10d28c36edd59a9d3b0e88","analyzedAt":"2026-08-14T22:02:06.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}