jackwener/OpenCLI · warning · EmptyResultError
npm registry returned 404 for ${url}.
Error message
npm registry returned 404 for ${url}. What it means
npmFetch wraps the public npm registry HTTP API (registry.npmjs.org / api.npmjs.org) and converts non-success responses into typed errors. When the endpoint answers HTTP 404, the URL could not be resolved to any known resource, so npmFetch throws EmptyResultError to signal 'nothing found' rather than a hard failure. Callers (like the body wrapper) use this to distinguish missing packages from genuine network or server errors.
Source
Thrown at clis/npm/utils.js:57
if (n > maxValue) {
throw new ArgumentError(`npm ${label} must be <= ${maxValue}`);
}
return n;
}
export async function npmFetch(url, label) {
let resp;
try {
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
- Verify the package name spelling with `npm view <name>` or on npmjs.com before retrying
- Check the exact URL being fetched; for scoped packages ensure the name is URL-encoded correctly (e.g. @babel%2fcore)
- If the package was unpublished or renamed, update to the correct/current name
- Handle EmptyResultError distinctly in calling code so 'not found' is reported as an empty result, not a crash
Example fix
// before
const data = await npmFetch(`${NPM_REGISTRY}/${encodeURIComponent(name)}`, 'npm package');
// after
try {
const data = await npmFetch(`${NPM_REGISTRY}/${encodeURIComponent(name)}`, 'npm package');
} catch (err) {
if (err instanceof EmptyResultError) {
console.error(`Package "${name}" was not found on the npm registry.`);
return null;
}
throw err;
} Defensive patterns
Strategy: try-catch
Validate before calling
function isValidNpmName(name) {
const s = String(name ?? '').trim();
return s.length > 0 && s.length <= 214 &&
/^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/i.test(s);
}
if (!isValidNpmName(pkg)) throw new Error(`Invalid npm package name: ${pkg}`); Type guard
function isEmptyResultError(err) {
return err instanceof Error && err.name === 'EmptyResultError';
} Try / catch
try {
const data = await npmFetch(`${NPM_REGISTRY}/${encodeURIComponent(pkg)}`, 'npm package');
return data;
} catch (err) {
if (err instanceof EmptyResultError || isEmptyResultError(err)) {
return null; // package not found — treat as empty result
}
throw err;
} Prevention
- Validate package names against the npm naming rules before calling the API
- URL-encode scoped package names (e.g. encodeURIComponent handles '@scope/name' → '@scope%2Fname')
- Check the package exists on npmjs.com when a query result is surprising
- Treat EmptyResultError as 'no data' rather than a crash in pipelines processing many packages
When it happens
Trigger: Any npmFetch call whose URL resolves to HTTP 404: fetching metadata for a package name that does not exist on the registry, a misspelled or renamed package, a scoped package without correct URL-encoding (e.g. '@scope/name' not encoded as @scope%2fname), or a deleted/unpublished package.
Common situations: Typos in a package name passed by a user ('reactt' instead of 'react'); querying a private-scope package on the public registry where it was never published; packages removed by npm for policy violations; stale scripts referencing packages that were renamed or deprecated.
Related errors
- Chess.com returned 404 for ${url}
- crates.io returned 404 for ${url}.
- Flathub returned 404 for ${url}.
- hf paper
- Homebrew API returned 404 for ${url}.
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/17e6dbb9f4be9e7c.
Report an issue: GitHub.