{"record":{"id":"6c0d3f02af4d7ee3","repo":"odysseus-dev/odysseus","slug":"not-authenticated-6c0d3f","errorCode":null,"errorMessage":"Not authenticated","messagePattern":"Not authenticated","errorType":"http","errorClass":"HTTPException","httpStatus":401,"severity":"error","filePath":"routes/research/research_routes.py","lineNumber":221,"sourceCode":"            pass\n    if not ep_model:\n        return None\n    return build_chat_url(base), ep_model, build_headers(api_key, base)\n\n\ndef setup_research_routes(research_handler, session_manager=None) -> APIRouter:\n    router = APIRouter(tags=[\"research\"])\n\n    def _require_user(request: Request) -> str:\n        \"\"\"All research endpoints require an authenticated user. Research\n        data isn't owner-scoped in the on-disk JSON yet, so we at least\n        block anonymous access. Multi-tenant deploys should additionally\n        verify the session belongs to this user.\"\"\"\n        user = get_current_user(request)\n        if not user:\n            if _auth_disabled():\n                return \"\"\n            raise HTTPException(401, \"Not authenticated\")\n        return user\n\n    def _owns_in_memory(session_id: str, user: str) -> bool:\n        \"\"\"Ownership check for an in-flight (in-memory) research task.\n        Falls back to the on-disk JSON if the task has already finished.\"\"\"\n        entry = research_handler._active_tasks.get(session_id)\n        if entry is not None:\n            return entry.get(\"owner\", \"\") == user\n        # Task no longer in memory — check the persisted JSON.\n        try:\n            return _find_owned_research_path(session_id, user) is not None\n        except HTTPException:\n            return False\n\n    def _require_owned_or_active_research_path(session_id: str, user: str) -> Path | None:\n        \"\"\"Validate ownership once and return the completed on-disk path.\n\n        Active running research has no completed disk path yet. Completed","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/odysseus-dev/odysseus/blob/f9235ebbf13f693a6fd29ce70b097f6ec83705bf/routes/research/research_routes.py#L203-L239","documentation":"Error \"Not authenticated\" thrown in odysseus-dev/odysseus.","triggerScenarios":"Triggered when the corresponding server-side validation or runtime check at the recorded location rejects the request or operation and returns this error message to the caller.","commonSituations":"See trigger scenarios.","solutions":["Log in and retry the request.","Refresh the page if the session expired."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"f9235ebbf13f693a6fd29ce70b097f6ec83705bf","analyzedAt":"2026-08-14T21:47:48.359Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}