odysseus-dev/odysseus · error · Error
Server returned no session id
Error message
Server returned no session id
What it means
Thrown in the same _chatAboutResearch flow (research/panel.js:1239) when the spinoff endpoint returns 200 OK but the JSON payload has no session_id. Per the inline comment this is a server contract violation: success status without the field needed to route the user to the new chat. The button is un-stuck and the failure alerted rather than silently ignored.
Source
Thrown at static/js/research/panel.js:1239:1239
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');
}View on GitHub (pinned to f9235ebbf1)
Solutions
- Inspect the actual 200 response body in the network tab to see which field holds the id.
- Update the client to read the current field name, or the server to emit session_id.
- Ensure client and server builds are from the same release.
- Fix test/mocks to include session_id.
Defensive patterns
Strategy: type-guard
Type guard
const isSpinoffPayload = (p) => !!p && (typeof p.session_id === 'string' || typeof p.session_id === 'number');
Try / catch
try { const payload = await res.json(); if (!isSpinoffPayload(payload)) throw new Error('Server returned no session id'); } catch (e) { btn.disabled = false; btn.innerHTML = origLabel; alert('Could not start follow-up chat: ' + e.message); } Prevention
- Never return 200 without the contract fields — use 502/500 for partial failures
- Validate response shape before navigating
- Add integration tests asserting session_id presence
When it happens
Trigger: Backend version that returns {chat_id} instead of {session_id}; a proxy or middleware stripping/rewriting the response body; server short-circuits with an empty object on partial creation (session created but id serialization failed).
Common situations: Client/server version skew after renaming the response field; mock servers returning incomplete payloads; serialization bugs where the ORM id is not included.
Related errors
- ${cfg.label} sign-in did not return a poll id
- detail || `HTTP ${res.status}`
- Session request returned an invalid response
- HTTP ' + r.status
- detail || ('HTTP ' + res.status)
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/130385bceeaedd27.
Report an issue: GitHub.