jackwener/OpenCLI · error · CommandExecutionError

${label} returned HTTP ${resp.status}

Error message

${label} returned HTTP ${resp.status}

What it means

This is npmFetch's catch-all for any HTTP status that is not 404 or 429 but still not ok (resp.ok is false for status >= 400). The helper throws CommandExecutionError with the raw status code, since no specific remediation is known. It surfaces unexpected server-side conditions (5xx) or unusual client errors (401/403) that the registry API returns outside its normal contract.

Source

Thrown at clis/npm/utils.js:66

        resp = await fetch(url, { headers: { 'user-agent': UA, accept: 'application/json' } });
    }
    catch (err) {
        throw new CommandExecutionError(
            `${label} request failed: ${err?.message ?? err}`,
            'Check that registry.npmjs.org / api.npmjs.org are reachable from this network.',
        );
    }
    if (resp.status === 404) {
        throw new EmptyResultError(label, `npm registry returned 404 for ${url}.`);
    }
    if (resp.status === 429) {
        throw new CommandExecutionError(
            `${label} returned HTTP 429 (rate limited)`,
            'npm throttles unauthenticated bursts; 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;
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Check the status code in the message: 5xx means a server-side problem — check https://status.npmjs.org and retry later
  2. 401/403 usually means a proxy or firewall is intercepting; inspect HTTP(S)_PROXY settings and corporate network policies
  3. Retry the request after a short delay — many 5xx conditions are transient
  4. If it persists, verify the URL manually with `curl -i <url>` to see the full response and any proxy-injected body

Example fix

// before
const data = await npmFetch(url, 'npm package');
// after
try {
  const data = await npmFetch(url, 'npm package');
} catch (err) {
  const m = /HTTP (\d{3})/.exec(err.message);
  if (m && Number(m[1]) >= 500) {
    console.error('npm registry is having issues; retry later.');
  }
  throw err;
}
Defensive patterns

Strategy: retry

Validate before calling

null

Type guard

null

Try / catch

try {
  return await npmFetch(url, label);
} catch (err) {
  const m = /HTTP (\d{3})/.exec(String(err.message));
  const status = m ? Number(m[1]) : 0;
  if (status >= 500 || status === 408) {
    await sleep(1000);
    return await npmFetch(url, label); // transient server error — retry once
  }
  if (status === 401 || status === 403) {
    throw new Error('Proxy/firewall blocked the request; check HTTP(S)_PROXY and network policy.');
  }
  throw err;
}

Prevention

When it happens

Trigger: npmFetch receives a response with status >= 400 other than 404/429: registry 5xx outages or partial failures, 401/403 from an internal proxy or firewall intercepting the request, 405/406 from an incompatible endpoint, or 502/503/504 from a reverse proxy in front of the registry.

Common situations: Corporate proxies or DNS filters returning 403 for unknown hosts; npm registry incidents producing 5xx responses; misconfigured HTTP_PROXY/HTTPS_PROXY env vars routing requests through a broken proxy; hitting a mirror endpoint that doesn't support the requested route.

Related errors


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