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
- curl -i '/api/cookbook/packages?host=...&ssh_port=...&venv=...' with the same params to see the real error body
- Verify the SSH target manually: ssh -p <port> <host> true
- Check the venv path exists on the target
- 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
- Degrade gracefully: a failed readiness probe should show 'unavailable', not break the serve panel
- Add a short timeout (AbortSignal.timeout) around SSH-backed probes so they can't hang the UI
- Log the full body server-side; surface only detail to users
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
- data.detail || data.error || `HTTP ${res.status}`
- HTTP ${res.status} ${res.statusText}${msg ? `: ${msg}` : ''}
- data.error || 'Failed to generate SSH key'
- HTTP ${res.status}
- detail || ('HTTP ' + res.status)
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/a5ebfb8577a43167.
Report an issue: GitHub.