odysseus-dev/odysseus · warning · Error

HTTP ${res.status}

Error message

HTTP ${res.status}

What it means

Error thrown when fetching cookbook package readiness: GET /api/cookbook/packages (optionally with host/ssh_port/venv/model_hint query params) returns non-OK, aborting the serve-runtime readiness note computation. Only 'HTTP <status>' is surfaced.

Source

Thrown at static/js/cookbookServe.js:837

    vllm: 'vllm',
    sglang: 'sglang',
    llamacpp: 'llama_cpp',
    mlx: 'mlx_lm',
    mlx_image: 'mflux',
    diffusers: 'diffusers',
  };
  const packageName = _dependencyPkgForServeBackend(backend, repo) || packageByBackend[backend];
  if (!packageName) return null;
  const target = _selectedServeTarget(panel);
  const params = new URLSearchParams();
  if (target.host) {
    params.set('host', target.host);
    if (target.port) params.set('ssh_port', target.port);
    if (target.venv) params.set('venv', target.venv);
  }
  if (repo) params.set('model_hint', repo);
  const res = await fetch('/api/cookbook/packages' + (params.toString() ? '?' + params.toString() : ''), { credentials: 'same-origin' });
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  const data = await res.json();
  const pkg = (data.packages || []).find(p => p.name === packageName);
  return { pkg, target };
}

function _runtimeNoteText(backend, pkg, target) {
  const labels = { vllm: 'vLLM', sglang: 'SGLang', llamacpp: 'llama.cpp', mlx: 'MLX', mlx_image: 'MLX Image', diffusers: 'Diffusers' };
  const label = labels[backend] || backend;
  if (!pkg) return `${label} readiness unavailable for ${target.label}.`;
  const note = pkg.status_note || pkg.update_note || '';
  if (pkg.installed === null || pkg.probe_error) {
    return note ? `${label} readiness unavailable for ${target.label}: ${note}` : `${label} readiness unavailable for ${target.label}.`;
  }
  if (pkg.installed) {
    return note ? `${label} ready on ${target.label}: ${note}` : `${label} ready on ${target.label}.`;
  }
  return note ? `${label} missing on ${target.label}: ${note}` : `${label} missing on ${target.label}.`;
}

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. curl -i '/api/cookbook/packages?host=...&ssh_port=...&venv=...' with the same params to see the real error body
  2. Verify the SSH target manually: ssh -p <port> <host> true
  3. Check the venv path exists on the target
  4. Inspect backend logs for the exception behind the 500

Example fix

// before
if (!res.ok) throw new Error(`HTTP ${res.status}`);

// after
if (!res.ok) {
  const body = await res.text().catch(() => '');
  let msg = '';
  try { msg = JSON.parse(body).detail || ''; } catch { msg = body.slice(0, 160); }
  throw new Error(`HTTP ${res.status}${msg ? ': ' + msg : ''}`);
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (target.host && !target.host.includes('@')) return null; // probe needs user@host

Try / catch

try {
  const res = await fetch('/api/cookbook/packages' + (params.toString() ? '?' + params.toString() : ''), { credentials: 'same-origin' });
  if (!res.ok) {
    const body = await res.text().catch(() => '');
    let msg = '';
    try { msg = JSON.parse(body).detail || ''; } catch { msg = body.slice(0, 160); }
    throw new Error(`HTTP ${res.status}${msg ? ': ' + msg : ''}`);
  }
  const data = await res.json();
  return { pkg: (data.packages || []).find(p => p.name === packageName), target };
} catch (e) {
  return { pkg: null, target }; // callers already render 'readiness unavailable' for missing pkg
}

Prevention

When it happens

Trigger: GET /api/cookbook/packages returns 500 (probe of the remote host crashed — ssh failure, venv path invalid), 422 (malformed port), or 404 after a route change; when host is set the backend shells out over SSH and any unhandled ssh error becomes a 500.

Common situations: SSH target unreachable or credentials rejected so the package probe throws server-side; venv parameter points to a non-existent directory; backend/frontend version skew renaming the route; slow SSH probes hitting a proxy timeout.

Related errors


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