odysseus-dev/odysseus · error · Error
HTTP ${response.status}
Error message
HTTP ${response.status} What it means
Error thrown when the compare-mode streaming request POST /api/chat_stream returns a non-OK status before any SSE/stream data is read. The message is only 'HTTP <status>' — no response body is inspected, so the cause is opaque from the UI.
Source
Thrown at static/js/compare/stream.js:261
}
const incognitoChk = document.getElementById('incognito-toggle');
if (incognitoChk && incognitoChk.checked) {
fd.append('incognito', 'true');
}
// Disable document tool and memory injection in compare mode
fd.append('no_documents', 'true');
fd.append('no_memory', 'true');
// Tell backend this is compare mode — strip all non-toggled tools
fd.append('compare_mode', 'true');
// Forward preset if selected
if (presetsModule && presetsModule.getSelectedPreset()) {
fd.append('preset_id', presetsModule.getSelectedPreset());
}
const response = await fetch(`${state.API_BASE}/api/chat_stream`, {
method: 'POST', body: fd, signal: ac.signal
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
_resetIdleTimeout(); // any chunk = stream is alive
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split('\n');
buffer = lines.pop() || '';
for (const line of lines) {
if (!line.startsWith('data: ')) continue;
const data = line.slice(6);
if (data === '[DONE]') break;View on GitHub (pinned to f9235ebbf1)
Solutions
- Reproduce with curl -i -X POST the same multipart body to read the status and error body the code discards
- Verify the session id sent in the form actually exists (it should be the one returned by POST /api/session)
- If a preset_id is appended, confirm that preset still exists server-side or drop it
- Improve the error to include the body: read response.text() before throwing
Example fix
// before
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// after
if (!response.ok) {
const body = await response.text().catch(() => '');
let detail = body;
try { detail = JSON.parse(body).detail || body; } catch {}
throw new Error(`HTTP ${response.status}: ${String(detail).slice(0, 200)}`);
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!fd.get('session')) { throw new Error('No session id to stream against'); }
if (presetsModule?.getSelectedPreset && presetsModule.getSelectedPreset() == null) fd.delete('preset_id'); Try / catch
try {
const response = await fetch(`${state.API_BASE}/api/chat_stream`, { method: 'POST', body: fd, signal: ac.signal });
if (!response.ok) {
const body = await response.text().catch(() => '');
let detail = body;
try { detail = JSON.parse(body).detail || body; } catch {}
throw new Error(`HTTP ${response.status}: ${String(detail).slice(0, 200)}`);
}
// ... read stream
} catch (e) {
if (e.name === 'AbortError') return; // user cancelled — not an error
showCompareError(e.message);
} Prevention
- Always read the error body on non-OK stream responses before throwing
- Distinguish AbortError from real failures in the catch
- Verify the session id and preset id exist before starting the stream
When it happens
Trigger: POST /api/chat_stream (multipart with no_documents, no_memory, compare_mode, optional preset_id) returns 404 (unknown session), 400 (invalid preset_id), 422 (missing fields), or 500 (backend exception before the stream starts).
Common situations: Session id from the create call is stale or invalid; preset selected in the UI was deleted server-side; backend restarted mid-compare; reverse proxy (nginx) returns 502/504 before the stream begins; compare_mode flag unsupported on older backend.
Related errors
- errData.detail || 'Failed to create session'
- detail || ('HTTP ' + res.status)
- HTTP ${res.status} ${res.statusText}${msg ? `: ${msg}` : ''}
- data.detail || data.error || `HTTP ${res.status}`
- HTTP ${res.status}
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/d9340d76548e2aa7.
Report an issue: GitHub.