{"record":{"id":"b962174519411106","repo":"infiniflow/ragflow","slug":"session-not-found","errorCode":null,"errorMessage":"Session not found!","messagePattern":"Session not found!","errorType":"exception","errorClass":"LookupError","httpStatus":null,"severity":"error","filePath":"api/db/services/canvas_service.py","lineNumber":369,"sourceCode":"        if not isinstance(dsl, str):\n            dsl = json.dumps(dsl, ensure_ascii=False)\n\n        return cvs, dsl\n\n\nasync def completion(tenant_id, agent_id, session_id=None, **kwargs):\n    query = kwargs.get(\"query\", \"\") or kwargs.get(\"question\", \"\")\n    files = kwargs.get(\"files\", [])\n    inputs = kwargs.get(\"inputs\", {})\n    user_id = kwargs.get(\"user_id\", \"\")\n    chat_template_kwargs = kwargs.get(\"chat_template_kwargs\")\n    custom_header = kwargs.get(\"custom_header\", \"\")\n    release_mode = str(kwargs.get(\"release\", \"\")).strip().lower()\n\n    if session_id:\n        e, conv = await thread_pool_exec(API4ConversationService.get_by_id, session_id)\n        if not e:\n            raise LookupError(\"Session not found!\")\n        if not conv.message:\n            conv.message = []\n        if not isinstance(conv.dsl, str):\n            conv.dsl = json.dumps(conv.dsl, ensure_ascii=False)\n        canvas = Canvas(conv.dsl, tenant_id, task_id=session_id, canvas_id=agent_id, custom_header=custom_header)\n    else:\n        cvs, dsl = await thread_pool_exec(UserCanvasService.get_agent_dsl_with_release, agent_id, release_mode=release_mode == \"true\", tenant_id=tenant_id)\n\n        session_id = get_uuid()\n        canvas = Canvas(dsl, tenant_id, task_id=session_id, canvas_id=cvs.id, custom_header=custom_header)\n        canvas.reset()\n        # Get the version title based on release_mode\n        version_title = await thread_pool_exec(UserCanvasVersionService.get_latest_version_title, cvs.id, release_mode=release_mode == \"true\")\n        conv = {\"id\": session_id, \"dialog_id\": cvs.id, \"user_id\": user_id, \"message\": [], \"source\": \"agent\", \"dsl\": dsl, \"reference\": [], \"version_title\": version_title}\n        await thread_pool_exec(API4ConversationService.save, **conv)\n        conv = API4Conversation(**conv)\n\n    message_id = str(uuid4())","sourceCodeStart":351,"sourceCodeEnd":387,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/api/db/services/canvas_service.py#L351-L387","documentation":"LookupError raised in the canvas completion() flow when a session_id was supplied but API4ConversationService.get_by_id(session_id) returns nothing: the conversation/session row for that agent chat no longer exists. The session carries its own DSL copy, so a missing session cannot be resumed; callers should start a new session instead.","triggerScenarios":"Calling the agent completion API with a session_id that was deleted (session cleared by the user), expired/purged, or belongs to another deployment; passing an agent id where a session id is expected.","commonSituations":"Chat history purged by the user or a retention job while a client still held the id; browser tab resumed after DB reset; scripts replaying recorded session ids against a fresh environment.","solutions":["Verify the session exists (API4ConversationService.get_by_id) before resuming; if gone, create a new session (omit session_id) and restart the conversation.","If sessions are being purged, keep client-side session handles in sync or stop purging sessions still in use.","Confirm you are passing the conversation/session id returned by a prior completion call, not the agent id.","Catch LookupError in clients and silently start a fresh session."],"exampleFix":"# before\nresp = await completion(tenant_id, agent_id, session_id=old_session)\n\n# after\nexist, _ = await thread_pool_exec(API4ConversationService.get_by_id, old_session)\nif not exist:\n    old_session = None  # start a new session\nresp = await completion(tenant_id, agent_id, session_id=old_session)","handlingStrategy":"fallback","validationCode":"if session_id:\n    exist, _ = await thread_pool_exec(API4ConversationService.get_by_id, session_id)\n    if not exist:\n        session_id = None  # start fresh instead of failing","typeGuard":null,"tryCatchPattern":"try:\n    resp = await completion(tenant_id, agent_id, session_id=sid)\nexcept LookupError as e:\n    if str(e) == \"Session not found!\":\n        resp = await completion(tenant_id, agent_id)  # new session","preventionTips":["Treat missing sessions as resumable-by-restart: fall back to a new session_id.","Sync client-side session lists when users purge chat histories.","Do not persist session ids across environment resets."],"tags":["session","conversation","agent","ragflow"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}