odysseus-dev/odysseus · error · Error

errData.detail || 'Failed to create session'

Error message

errData.detail || 'Failed to create session'

What it means

Error thrown while creating the synthesis session in compare mode: POST /api/session (multipart form) returned a non-OK status, and the parsed JSON 'detail' (or a generic message) becomes the error text. It aborts the whole compare/synthesis stream before it starts.

Source

Thrown at static/js/compare/stream.js:91

}

/** Run synthesis for a search pane — sends search results to an LLM for analysis. */
async function _runSynthForPane(modelToUse, synthPrompt, synthBody, spinner, hist) {
  // Create temp session for synthesis
  const fd = new FormData();
  fd.append('name', 'Synthesis');
  fd.append('endpoint_url', modelToUse.endpoint || '');
  fd.append('model', modelToUse.model || '');
  if (modelToUse.endpointId) {
    fd.append('endpoint_id', modelToUse.endpointId);
    fd.append('skip_validation', 'true');
  }

  try {
    const createRes = await fetch(`${state.API_BASE}/api/session`, { method: 'POST', body: fd });
    if (!createRes.ok) {
      const errData = await createRes.json().catch(() => ({}));
      throw new Error(errData.detail || 'Failed to create session');
    }
    const createData = await createRes.json();

    const synthAc = new AbortController();
    state._abortControllers.push(synthAc);
    const streamRes = await fetch(`${state.API_BASE}/api/chat_stream`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ session: createData.id, message: synthPrompt }),
      signal: synthAc.signal,
    });

    if (spinner) spinner.stop();
    synthBody.innerHTML = '';
    const reader = streamRes.body.getReader();
    const decoder = new TextDecoder();
    let synthText = '';

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Inspect the response body of POST /api/session (curl -X POST with the same multipart fields) to see the validation 'detail'
  2. Confirm modelToUse.endpoint / modelToUse.model are non-empty and the endpoint_id still exists in the endpoints list
  3. Check server logs for the 4xx/5xx stack trace on session creation
  4. If 422, compare the form field names the backend expects (name, endpoint_url, model, endpoint_id) with what is appended

Example fix

// before
const errData = await createRes.json().catch(() => ({}));
throw new Error(errData.detail || 'Failed to create session');

// after
const errData = await createRes.json().catch(() => ({}));
throw new Error(errData.detail || `Failed to create session (HTTP ${createRes.status})`);
Defensive patterns

Strategy: validation

Validate before calling

if (!modelToUse || !(modelToUse.endpoint || modelToUse.endpointId) || !modelToUse.model) {
  throw new Error('Select a model endpoint before running the comparison');
}

Try / catch

try {
  const createRes = await fetch(`${state.API_BASE}/api/session`, { method: 'POST', body: fd });
  if (!createRes.ok) {
    const errData = await createRes.json().catch(() => ({}));
    throw new Error(errData.detail || `Failed to create session (HTTP ${createRes.status})`);
  }
  const createData = await createRes.json();
  // ... proceed to chat_stream
} catch (e) {
  state._abortControllers.length && state._abortControllers.pop();
  showCompareError('Synthesis failed: ' + e.message);
}

Prevention

When it happens

Trigger: POST /api/session fails with 422 (missing/invalid form fields such as name, endpoint_url, model), 400 (endpoint_id references a deleted endpoint), or 500. Then errData.detail is undefined when the body is not JSON, yielding the generic 'Failed to create session'.

Common situations: Selected model endpoint was removed or is unreachable so server-side validation rejects it; endpoint_id passed with skip_validation=true points to a stale row; required form field missing after a UI change; backend version mismatch on the /api/session contract.

Related errors


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