jackwener/OpenCLI · error · CommandExecutionError
${label} returned HTTP ${resp.status}
Error message
${label} returned HTTP ${resp.status} What it means
packagistFetch throws this when a Packagist HTTP request completes with a non-OK status other than the specially-handled 429. It signals the remote API rejected or failed the request without parsing a body. The library surfaces the raw HTTP status so callers can diagnose server- or request-side problems.
Source
Thrown at clis/packagist/utils.js:76
resp = await fetch(url, { headers: { 'user-agent': UA, accept: 'application/json' } });
}
catch (err) {
throw new CommandExecutionError(
`${label} request failed: ${err?.message ?? err}`,
'Check that packagist.org is reachable from this network.',
);
}
if (resp.status === 404) {
throw new EmptyResultError(label, `Packagist returned 404 for ${url}.`);
}
if (resp.status === 429) {
throw new CommandExecutionError(
`${label} returned HTTP 429 (rate limited)`,
'Packagist throttles 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;
}
/** Trim "2026-05-05T17:32:01+00:00" → "2026-05-05T17:32:01Z" so timestamps are uniform. */
export function trimDate(value) {
const s = String(value ?? '').trim();
if (!s) return null;
const noFrac = s.replace(/\.\d+/, '');
return noFrac.replace(/(?:[+-]\d{2}:?\d{2}|Z)?$/, 'Z');
}View on GitHub (pinned to 49907e53dc)
Solutions
- Verify the package name/vendor spelling exactly matches Packagist (case-sensitive vendor).
- Check https://packagist.org in a browser or `curl -I` the API URL to confirm the status is reproducible.
- Retry later if the status is 5xx (Packagist-side outage).
- Check proxy/VPN/firewall settings if the status is 403.
Example fix
// before
const data = await body('symfony/does-not-exist');
// after
let data;
try { data = await body('symfony/console'); }
catch (e) { console.error(`Lookup failed: ${e.message}`); } Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check the resource exists on Packagist (optional)
const res = await fetch(`https://repo.packagist.org/p2/${name}.json`);
if (!res.ok) throw new Error(`Package ${name} unreachable: HTTP ${res.status}`); Try / catch
try {
const data = await body(pkg);
} catch (err) {
if (/HTTP 404/.test(err.message)) console.error(`Unknown package: ${pkg}`);
else if (/HTTP 5\d\d/.test(err.message)) retryLater();
else throw err;
} Prevention
- Double-check package vendor/name spelling against packagist.org.
- Handle 429 and 5xx with backoff before giving up.
- Monitor Packagist status during CI runs.
When it happens
Trigger: Calling any packagistFetch-backed command (body/lookup helpers) when Packagist returns 4xx/5xx other than 429: 404 for an unknown package, 403 for blocked requests, 5xx during Packagist outages.
Common situations: Typos in package vendor/name causing 404; Packagist returning 503 during maintenance; corporate proxies rejecting the request with 403; deprecated or removed packages.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- 12306 queryByTrainNo returned HTTP ${resp.status}
- 12306 queryByTrainNo returned non-JSON body
- 12306 ${endpoint} returned non-JSON body
- 1point3acres request failed: HTTP ${res.status} ${res.status
- ${label} returned HTTP ${resp.status}: ${summarizeApiError(p
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/555880b18d7232d0.
Report an issue: GitHub.