pbakaus/impeccable · error · Error
Status failed: ${res.status} ${res.statusText}
Error message
Status failed: ${res.status} ${res.statusText} What it means
Thrown by fetchServerStatus() in live-poll.mjs when GET {base}/status?token=... returns a non-OK status other than 401. A 401 is handled separately with an AUTH_FAILED error code; every other failure (5xx, 404, 403) collapses to this generic message carrying the numeric status and statusText. The function returns res.json() on success, so any non-JSON or error response aborts the status handshake.
Source
Thrown at skill/scripts/live-poll.mjs:138
if (!res.ok) {
const body = await res.json().catch(() => ({}));
const failureLines = Array.isArray(body.failures)
? body.failures.map((f) => ` ${f.file}${f.line != null ? `:${f.line}` : ''} ${f.message}`).join('\n')
: null;
const parts = [body.error || res.statusText, body.reason, body.hint, failureLines, body._instructions].filter(Boolean);
throw new Error(parts.join('\n'));
}
}
export async function fetchServerStatus(base, token) {
const res = await fetch(`${base}/status?token=${token}`);
if (res.status === 401) {
const err = new Error('Authentication failed. The server token may have changed.');
err.code = 'AUTH_FAILED';
throw err;
}
if (!res.ok) {
throw new Error(`Status failed: ${res.status} ${res.statusText}`);
}
return res.json();
}
export function isEventPending(status, eventId) {
return (status.pendingEvents || []).some((entry) => entry.id === eventId);
}
export async function waitForEventAck(base, token, eventId, {
pollIntervalMs = 400,
maxWaitMs = 600_000,
} = {}) {
const deadline = Date.now() + maxWaitMs;
while (Date.now() < deadline) {
const status = await fetchServerStatus(base, token);
if (!isEventPending(status, eventId)) return true;
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
}View on GitHub (pinned to d14711ae3d)
Solutions
- Confirm the base URL and port point at the Impeccable Live server (not the app dev server or a proxy).
- Check the server process is alive and inspect its logs for the matching status code.
- If 401-style but reported as 403, verify the token matches the one the server booted with.
- Retry once the server is healthy; persistent 5xx indicates a server bug to file.
Defensive patterns
Strategy: retry
Validate before calling
// Cheap preflight before the status handshake.
async function isReachable(base) {
try { const r = await fetch(base, { method: 'HEAD' }); return r.ok || r.status < 500; } catch { return false; }
}
if (!(await isReachable(base))) throw new Error('live server unreachable at ' + base); Try / catch
try {
const status = await fetchServerStatus(base, token);
} catch (err) {
if (err.code === 'AUTH_FAILED') throw err; // re-raise auth, handled elsewhere
// transient server error — back off and retry with jitter
console.warn('status fetch failed:', err.message);
throw err;
} Prevention
- Keep the base URL in a single config source to avoid pointing at the wrong server.
- Add a health check (GET /status) at agent startup before entering the poll loop.
- Distinguish 401 (auth) from other statuses; only retry transient 5xx with backoff.
When it happens
Trigger: fetchServerStatus(base, token) is invoked (by waitForEventAck, the live agent loop, or a manual health check) and the server responds with e.g. 500 Internal Server Error, 502 Bad Gateway, 404 (wrong base URL), or 403. A 401 would have thrown 'Authentication failed' with code AUTH_FAILED instead.
Common situations: Live server crashed or is restarting (5xx); base URL is wrong/proxied and hits a different service (404); reverse proxy or Cloudflare Pages Functions returned an error page; server version mismatch where /status route was renamed; port confusion pointing at a different dev server.
Related errors
- ${parts.join('\n')}
- Poll failed: ${res.status} ${res.statusText}
- ${body.error || res.statusText}\n${body.reason}\n${body.hint
- Status failed: ${res.status} ${res.statusText}
- Poll failed: ${res.status} ${res.statusText}
AI-assisted analysis of pbakaus/impeccable@d14711ae3d (2026-08-13).
Data as JSON: /api/errors/241e50e7b1bfe963.
Report an issue: GitHub.