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

  1. 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>
  2. Retry after a short wait for 5xx statuses; TVmaze may be having an incident
  3. Confirm the request URL is a valid https://api.tvmaze.com endpoint
  4. 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

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


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/7d86ebd4390adfd1. Report an issue: GitHub.