{"record":{"id":"dfea7a9a5353a5c1","repo":"odysseus-dev/odysseus","slug":"failed-to-load-research","errorCode":null,"errorMessage":"Failed to load research","messagePattern":"Failed to load research","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"static/js/sessions.js","lineNumber":3458,"sourceCode":"        e.stopPropagation();\n        _showDropdown(e.currentTarget, [\n          { label: 'Open', action: () => { if (d.session_id) { closeLibrary(); selectSession(d.session_id); } } },\n          { label: 'Delete', action: async () => { if (!await uiModule.styledConfirm('Delete?', { confirmText: 'Delete', danger: true })) return; await fetch(`${API_BASE}/api/document/${d.id}`, { method: 'DELETE' }); _renderLibGrid(); }, danger: true },\n        ]);\n      });\n      grid.appendChild(card);\n    }\n  } catch (e) { console.error('Library documents error:', e); grid.innerHTML = '<div class=\"doclib-empty\">Failed to load documents</div>'; }\n}\n\nasync function _renderLibResearch(grid) {\n  grid.innerHTML = '';\n  grid.appendChild(spinnerModule.createLoadingRow('Loading research…'));\n  try {\n    const params = new URLSearchParams({ limit: '50', sort: _lib.sort });\n    if (_lib.search) params.set('search', _lib.search);\n    const res = await fetch(`${API_BASE}/api/research/library?${params}`);\n    if (!res.ok) throw new Error(res.status);\n    const data = await res.json();\n    const items = data.research || [];\n    const statsEl = document.getElementById('lib-stats');\n    if (statsEl) statsEl.textContent = `${data.total || 0} research`;\n    grid.innerHTML = '';\n    if (!items.length) {\n      grid.innerHTML = '<div class=\"doclib-empty\">No research found</div>';\n      return;\n    }\n    for (const item of items) {\n      const meta = [\n        item.duration || '',\n        item.rounds ? item.rounds + ' rounds' : '',\n      ].filter(Boolean).join(' \\u00b7 ');\n      const card = _buildLibCard(\n        item.id, item.query || '(untitled)', item.source_count || 0,\n        meta, item.completed_at ? new Date(item.completed_at * 1000).toISOString() : '',\n        false, false,","sourceCodeStart":3440,"sourceCodeEnd":3476,"githubUrl":"https://github.com/odysseus-dev/odysseus/blob/f9235ebbf13f693a6fd29ce70b097f6ec83705bf/static/js/sessions.js#L3440-L3476","documentation":"Inline grid message shown when loading the research library fails. _renderLibResearch fetches /api/research/library with limit/sort/search params and throws new Error(res.status) on any non-OK response; note the error is created but this outer handler renders 'Failed to load research' (the sibling documents grid shows the analogous text).","triggerScenarios":"GET /api/research/library?limit=50&sort=...&search=... returns non-2xx — malformed sort param, invalid search encoding, 401 — or the fetch itself rejects (server down, offline).","commonSituations":"Backend not running or restarted; auth expired while library tab open; an unsupported sort value left in module state; very large search strings breaking the query.","solutions":["Read the actual status from the network tab (the thrown Error carries it)","Verify the sort/search values are among the API's accepted values","Re-login if 401; restart/health-check the backend if connection refused","Catch and display e.message (the status) in the empty-state instead of a fixed string"],"exampleFix":"// before\n  } catch (e) {\n    grid.innerHTML = '<div class=\"doclib-empty\">Failed to load research</div>';\n  }\n\n// after\n  } catch (e) {\n    console.error('library research error:', e);\n    grid.innerHTML = `<div class=\"doclib-empty\">Failed to load research (${e.message})</div>`;\n  }","handlingStrategy":"try-catch","validationCode":"const VALID_SORTS = ['newest','oldest'];\nif (!VALID_SORTS.includes(_lib.sort)) _lib.sort = 'newest';\nif (!navigator.onLine) { grid.innerHTML = '<div class=\"doclib-empty\">Offline</div>'; return; }","typeGuard":null,"tryCatchPattern":"try { const res = await fetch(url); if (!res.ok) throw new Error(`HTTP ${res.status}`); ... } catch (e) { grid.innerHTML = `<div class=\"doclib-empty\">Failed to load research (${e.message})</div>`; }","preventionTips":["Whitelist sort/search values against the API contract","Handle 401 with a re-login prompt instead of an error row","Show the HTTP status in the empty-state","Abort in-flight loads when the tab changes to avoid race-rendered errors"],"tags":["network","fetch","ui","research-library"],"backgroundTag":null,"analyzedSha":"f9235ebbf13f693a6fd29ce70b097f6ec83705bf","analyzedAt":"2026-08-14T21:47:48.359Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}