jackwener/OpenCLI · error · CommandExecutionError
${label} returned HTTP ${resp.status}
Error message
${label} returned HTTP ${resp.status} What it means
tvmazeFetch wraps every HTTP call to the TVmaze REST API. When a response arrives with a non-ok status that is not the specially-handled 429 case, it throws a CommandExecutionError embedding the label (e.g. 'search' or 'show') and the HTTP status code. This surfaces network/API failures like 404 (unknown show id), 400, or 5xx as a user-facing command error.
Source
Thrown at clis/tvmaze/utils.js:61
resp = await fetch(url, { headers: { 'user-agent': UA, accept: 'application/json' } });
}
catch (err) {
throw new CommandExecutionError(
`${label} request failed: ${err?.message ?? err}`,
'Check that api.tvmaze.com is reachable from this network.',
);
}
if (resp.status === 404) {
throw new EmptyResultError(label, `TVmaze returned 404 for ${url}.`);
}
if (resp.status === 429) {
throw new CommandExecutionError(
`${label} returned HTTP 429 (rate limited)`,
'TVmaze caps unauthenticated traffic at ~20 req/10s; wait a few seconds and retry.',
);
}
if (!resp.ok) {
throw new CommandExecutionError(`${label} returned HTTP ${resp.status}`);
}
let body;
try {
body = await resp.json();
}
catch (err) {
throw new CommandExecutionError(`${label} returned malformed JSON: ${err?.message ?? err}`);
}
return body;
}
const HTML_ENTITY_MAP = {
amp: '&',
lt: '<',
gt: '>',
quot: '"',
apos: "'",
nbsp: ' ',View on GitHub (pinned to 49907e53dc)
Solutions
- Check the status code in the message: 404 usually means the show id or endpoint path is wrong — verify the id at tvmaze.com/shows/<id>
- Retry after a short wait for 5xx statuses; TVmaze may be having an incident
- Confirm the request URL is a valid https://api.tvmaze.com endpoint
- For 429s see the separate rate-limit message with explicit guidance
Example fix
// before
await tvmazeFetch(`${TVMAZE_BASE}/shows/${rawId}`, 'show');
// after
const id = requireShowId(rawId); // validates before hitting the API
await tvmazeFetch(`${TVMAZE_BASE}/shows/${id}`, 'show'); Defensive patterns
Strategy: retry
Validate before calling
const id = requireShowId(rawId); // validate inputs before calling tvmazeFetch
if (!Number.isInteger(id) || id <= 0) throw new Error('invalid show id'); Type guard
function isHttpResponseOk(resp) { return typeof resp.status === 'number' && resp.status >= 200 && resp.status < 300; } Try / catch
try {
const data = await tvmazeFetch(url, 'show');
} catch (err) {
const m = /HTTP (\d{3})/.exec(err.message);
if (m && Number(m[1]) >= 500) return retryWithBackoff(url);
throw err; // 4xx: fix the request, don't retry
} Prevention
- Validate ids/queries with requireShowId/requireString before fetching
- Treat 4xx as caller errors and 5xx as retryable
- Check https://www.tvmaze.com/api for endpoint validity
- Watch for the explicit 429 message and back off
When it happens
Trigger: The list or show commands call tvmazeFetch and api.tvmaze.com responds with an HTTP status other than 200 and other than 429 — e.g. 404 for an invalid show id path, 400 for a malformed query, or 5xx server errors.
Common situations: Typing a wrong TVmaze show id (404), typos in search terms producing unexpected endpoints, transient TVmaze server incidents (5xx), or a proxy/firewall returning error pages.
Related errors
- ${label} returned HTTP ${resp.status}: ${summarizeApiError(p
- HTTP ${result.httpStatus} from /api/organizations
- ${label} returned HTTP ${res.status}
- HTTP_ERROR
- HTTP_ERROR
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/7d86ebd4390adfd1.
Report an issue: GitHub.