{"record":{"id":"1739da989d9e92fe","repo":"odysseus-dev/odysseus","slug":"failed-to-restore-session","errorCode":null,"errorMessage":"Failed to restore session","messagePattern":"Failed to restore session","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"static/js/sessions.js","lineNumber":2956,"sourceCode":"    }\n    if (window.uiModule) window.uiModule.scrollHistory();\n  } catch (e) {\n    console.error('Peek open failed:', e);\n    uiModule.showError('Failed to open archived session');\n  }\n}\n\n// When navigating away from a peeked session, just clear the state\nfunction _checkPeekCleanup(newSessionId) {\n  if (_peekingSessionId && _peekingSessionId !== newSessionId) {\n    _peekingSessionId = null;\n  }\n}\n\nasync function _arcRestore(sid) {\n  try {\n    const res = await fetch(`${API_BASE}/api/session/${sid}/unarchive`, { method: 'POST' });\n    if (!res.ok) throw new Error('Failed');\n    _arcRemove(sid);\n    _arcRefreshUI();\n    uiModule.showToast('Session restored');\n    loadSessions();\n  } catch { uiModule.showError('Failed to restore session'); }\n}\n\nasync function _arcDelete(sid) {\n  if (!await window.styledConfirm('Delete this session permanently?', { confirmText: 'Delete', danger: true })) return;\n  try {\n    const res = await fetch(`${API_BASE}/api/session/${sid}`, { method: 'DELETE' });\n    if (!res.ok) throw new Error('Failed');\n    await _animateSessionRowsRemoving([sid], '#archive-grid .archive-row[data-session-id]');\n    _arcRemove(sid);\n    _arcRefreshUI();\n    uiModule.showToast('Session deleted');\n  } catch { uiModule.showError('Failed to delete session'); }\n}","sourceCodeStart":2938,"sourceCodeEnd":2974,"githubUrl":"https://github.com/odysseus-dev/odysseus/blob/f9235ebbf13f693a6fd29ce70b097f6ec83705bf/static/js/sessions.js#L2938-L2974","documentation":"Toast shown when unarchiving a session fails. _arcRestore POSTs to /api/session/{sid}/unarchive and throws on any non-OK response; the bare catch also swallows failures in _arcRemove/_arcRefreshUI/loadSessions.","triggerScenarios":"POST /api/session/{sid}/unarchive returns non-2xx (sid not in archive on server, expired auth) or the fetch rejects (offline, server down); also any error thrown by the follow-up UI refresh.","commonSituations":"Archive list out of sync with server (session already restored/deleted elsewhere); backend restarted; auth session expired while the archive view was open.","solutions":["Check the unarchive request status in the browser network tab","Reload the archive view to resync ids, then retry","Verify auth cookie / re-login if endpoints return 401","Log the caught error instead of discarding it to pinpoint the failing step"],"exampleFix":"// before\n  } catch { uiModule.showError('Failed to restore session'); }\n\n// after\n  } catch (e) {\n    console.error('unarchive failed:', e);\n    uiModule.showError('Failed to restore session');\n  }","handlingStrategy":"try-catch","validationCode":"if (!sid) return;\nif (!navigator.onLine) { uiModule.showError('Offline — cannot restore session'); return; }","typeGuard":null,"tryCatchPattern":"try { const res = await fetch(url, opts); if (!res.ok) throw new Error(`HTTP ${res.status}`); ... } catch (e) { console.error('unarchive', sid, e); uiModule.showError('Failed to restore session'); }","preventionTips":["Resync the archive view before restoring","Verify auth credentials when endpoints start failing","Keep UI-refresh calls out of the guarded try block","Capture e in the catch (current code drops it)"],"tags":["network","fetch","ui","archive"],"backgroundTag":null,"analyzedSha":"f9235ebbf13f693a6fd29ce70b097f6ec83705bf","analyzedAt":"2026-08-14T21:47:48.359Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}