{"record":{"id":"908096b9c907f34b","repo":"odysseus-dev/odysseus","slug":"session-not-found","errorCode":null,"errorMessage":"Session not found","messagePattern":"Session not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"routes/chat_routes.py","lineNumber":2448,"sourceCode":"            if agent_runs.is_active(session_id):\n                return {\"status\": \"streaming\", \"detached\": True}\n            raise HTTPException(404, \"No active stream for this session\")\n        return rec\n\n    # ------------------------------------------------------------------ #\n    # POST /api/inject_context\n    # ------------------------------------------------------------------ #\n    @router.post(\"/api/inject_context/{session_id}\")\n    async def inject_context(request: Request, session_id: str, context: str = Form(...)) -> Dict[str, str]:\n        _verify_session_owner(request, session_id)\n        try:\n            sess = session_manager.get_session(session_id)\n            msg = untrusted_context_message(\"injected research context\", f\"Research Context: {context}\")\n            sess.add_message(ChatMessage(msg[\"role\"], msg[\"content\"], metadata=msg.get(\"metadata\")))\n            session_manager.save_sessions()\n            return {\"status\": \"context_injected\"}\n        except KeyError:\n            raise HTTPException(404, \"Session not found\")\n\n    # ------------------------------------------------------------------ #\n    # GET /api/search — search across chat messages\n    # ------------------------------------------------------------------ #\n    @router.get(\"/api/search\")\n    async def search_messages(\n        request: Request,\n        q: str = Query(\"\", min_length=0),\n        limit: int = Query(20, ge=1, le=100),\n    ) -> List[Dict[str, Any]]:\n        if not q or not q.strip():\n            return []\n\n        _user = effective_user(request)\n        return [\n            result.to_dict()\n            for result in search_session_messages(\n                q,","sourceCodeStart":2430,"sourceCodeEnd":2466,"githubUrl":"https://github.com/odysseus-dev/odysseus/blob/f9235ebbf13f693a6fd29ce70b097f6ec83705bf/routes/chat_routes.py#L2430-L2466","documentation":"POST /api/inject_context/{session_id} failed to load the session: get_session raised KeyError and the handler maps it to 404. Ownership is verified first, so a session owned by someone else also appears as not-found.","triggerScenarios":"Injecting research context into a session ID that was deleted, never existed, or belongs to another user; the 'context' form field is present but the session is gone.","commonSituations":"Research pipeline holding a stale session ID from before deletion/restart; orchestration code injecting into a session that another process already tore down.","solutions":["Resolve a fresh, owned session ID before injecting context","If the research flow spans long periods, re-verify the session exists right before injection","Handle 404 by recreating or re-targeting the session instead of retrying blindly"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"const sessions = await fetch('/api/sessions').then(r=>r.json());\nif (!sessions.some(s => s.id === sessionId)) { sessionId = await createSession(); }","typeGuard":null,"tryCatchPattern":"try { await injectContext(sessionId, ctx); } catch (e) { if (e.status === 404) { sessionId = await createSession(); await injectContext(sessionId, ctx); } else throw e; }","preventionTips":["Re-verify session existence immediately before long-pipeline injections","Propagate the new session ID back through the pipeline on 404 fallback"],"tags":["session","not-found","context-injection","http-404"],"backgroundTag":null,"analyzedSha":"f9235ebbf13f693a6fd29ce70b097f6ec83705bf","analyzedAt":"2026-08-14T21:47:48.359Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}