odysseus-dev/odysseus · error · Error

detail || `HTTP ${res.status}`

Error message

detail || `HTTP ${res.status}`

What it means

Thrown by _chatAboutResearch in research/panel.js when POST /api/research/spinoff/{researchId} fails. The client attempts to extract a FastAPI-style detail from the JSON body; if absent or unparseable it falls back to the bare HTTP status. The catch re-enables the button and alerts, so UI state is restored.

Source

Thrown at static/js/research/panel.js:1226

      setTimeout(() => { btn.innerHTML = orig; }, 2000);
    }
  }
}

// ── Chat about this research (server-side spinoff) ──

async function _chatAboutResearch(researchId, btn) {
  if (!researchId) return;
  const origLabel = btn ? btn.innerHTML : '';
  if (btn) { btn.disabled = true; btn.innerHTML = `${_chatIcon} Creating…`; }
  try {
    const res = await fetch(`${_apiBase}/api/research/spinoff/${researchId}`, {
      method: 'POST', credentials: 'same-origin',
    });
    if (!res.ok) {
      let detail = '';
      try { detail = (await res.json()).detail || ''; } catch {}
      throw new Error(detail || `HTTP ${res.status}`);
    }
    const payload = await res.json();
    if (_sessionModule && _sessionModule.selectSession && payload.session_id) {
      if (_sessionModule.loadSessions) await _sessionModule.loadSessions().catch(() => {});
      await _sessionModule.selectSession(payload.session_id);
      closePanel();
    } else if (payload.session_id) {
      window.location.hash = '#' + payload.session_id;
      window.location.reload();
    } else {
      // 200 OK but no session_id — server contract violation. Don't leave
      // the button stuck on 'Creating…'; surface the failure instead.
      throw new Error('Server returned no session id');
    }
  } catch (e) {
    if (btn) { btn.disabled = false; btn.innerHTML = origLabel; }
    alert('Could not start follow-up chat: ' + e.message);
  }

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Close and reopen the research panel to refresh ids, then retry.
  2. Read the detail in the alert for the server's reason; check server logs for 5xx.
  3. Re-authenticate if the status is 401.
  4. Verify the research entry still exists in the panel list.
Defensive patterns

Strategy: try-catch

Validate before calling

if (!researchId) { btn.disabled = false; return; }

Type guard

const isSpinoffPayload = (p) => !!p && !!p.session_id;

Try / catch

try { ... } catch (e) { btn.disabled = false; btn.innerHTML = origLabel; alert('Could not start follow-up chat: ' + e.message); }

Prevention

When it happens

Trigger: Creating a follow-up chat from a research report whose id no longer exists (404); research data deleted between panel open and click; server cannot create the spinoff session (db error → 500 with detail); auth expired (401 with empty body → 'HTTP 401').

Common situations: Stale research panel left open while the server restarted or the research store was cleared; long-lived tabs with expired sessions.

Related errors


AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14). Data as JSON: /api/errors/989ec95552bd6a05. Report an issue: GitHub.