{"record":{"id":"418eaabb5a8e332c","repo":"odysseus-dev/odysseus","slug":"failed-to-archive-session","errorCode":null,"errorMessage":"Failed to archive session","messagePattern":"Failed to archive session","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"static/js/sessions.js","lineNumber":926,"sourceCode":"    } catch (e) { /* network error — session may still exist server-side */ }\n    await loadSessions();\n  });\n\n  archiveItem.addEventListener('click', async () => {\n    dropdown.style.display = 'none';\n    _forceSidebarOpen();\n    try {\n      const response = await fetch(`${API_BASE}/api/session/${s.id}/archive`, {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json' }\n      });\n      if (response.ok) {\n        _forceSidebarOpen();\n        await loadSessions();\n        dropdown.style.display = 'none';\n        uiModule.showToast('Session archived');\n      } else {\n        throw new Error('Failed to archive session');\n      }\n    } catch (error) {\n      console.error('Error archiving session:', error);\n      uiModule.showError('Failed to archive session');\n    }\n  });\n\n  // Dropdowns are closed by the shared global listener (_initDropdownDismiss)\n\n  // Prevent dropdown from closing when clicking inside it\n  dropdown.addEventListener('click', (e) => {\n    e.stopPropagation();\n  });\n\n  div.appendChild(span);\n\n  // Apply processing/completed state to the star dot\n  var _isProcessing = _researchingSessions.has(s.id) || _streamingSessions.has(s.id);","sourceCodeStart":908,"sourceCodeEnd":944,"githubUrl":"https://github.com/odysseus-dev/odysseus/blob/f9235ebbf13f693a6fd29ce70b097f6ec83705bf/static/js/sessions.js#L908-L944","documentation":"Thrown by the archive action in sessions.js when POST /api/session/{id}/archive returns non-ok. The status and body are discarded entirely — the same fixed string is used both for the throw and the catch's showError, so 'Failed to archive session' carries no diagnostic information. The dropdown is simply left open.","triggerScenarios":"Archiving a session id the server no longer has (404, deleted elsewhere); session store write failure (500); missing credentials header handling — note this fetch sends Content-Type but not credentials:'same-origin', so a strict cookie policy can yield 401/302.","commonSituations":"Stale session list after another device deleted the conversation; cross-origin deployment where same-origin credentials are required but not sent; backend storage locked.","solutions":["Reload the session list (loadSessions) and retry on the current id.","If cross-origin, add credentials:'same-origin' to the fetch (see exampleFix).","Check server logs for the real status behind the generic message.","Include the status in the error text for future diagnosability."],"exampleFix":"// before\nconst response = await fetch(`${API_BASE}/api/session/${s.id}/archive`, {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' }\n});\nif (!response.ok) { throw new Error('Failed to archive session'); }\n\n// after\nconst response = await fetch(`${API_BASE}/api/session/${s.id}/archive`, {\n  method: 'POST',\n  credentials: 'same-origin',\n  headers: { 'Content-Type': 'application/json' }\n});\nif (!response.ok) { throw new Error(`Failed to archive session (HTTP ${response.status})`); }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { if (!response.ok) throw new Error(`Failed to archive session (HTTP ${response.status})`); await loadSessions(); } catch (error) { uiModule.showError('Failed to archive session'); dropdown.style.display = 'none'; }","preventionTips":["Send credentials:'same-origin' on every API fetch for cookie consistency","Include the status code in the message","Hide the dropdown in the error path too so UI state stays consistent"],"tags":["sessions","archive","http","credentials"],"backgroundTag":null,"analyzedSha":"f9235ebbf13f693a6fd29ce70b097f6ec83705bf","analyzedAt":"2026-08-14T21:47:48.359Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}