jackwener/OpenCLI · warning · EmptyResultError
OSV.dev returned 404 for ${url}.
Error message
OSV.dev returned 404 for ${url}. What it means
OSV.dev's API endpoint returned HTTP 404 for the requested URL. This library surfaces it as an EmptyResultError because a 404 from api.osv.dev means no vulnerability data exists at that resource (e.g. an unknown vulnerability ID), rather than a transient network failure.
Source
Thrown at clis/osv/utils.js:109
catch (err) {
throw new CommandExecutionError(`${label} returned malformed JSON: ${err?.message ?? err}`);
}
return body;
}
export async function osvGet(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 api.osv.dev is reachable from this network.',
);
}
if (resp.status === 404) {
throw new EmptyResultError(label, `OSV.dev returned 404 for ${url}.`);
}
if (resp.status === 429) {
throw new CommandExecutionError(`${label} returned HTTP 429 (rate limited)`);
}
if (!resp.ok) {
throw new CommandExecutionError(`${label} returned HTTP ${resp.status}`);
}
return readJson(resp, label);
}
export async function osvPost(url, payload, label) {
let resp;
try {
resp = await fetch(url, {
method: 'POST',
headers: { 'user-agent': UA, accept: 'application/json', 'content-type': 'application/json' },
body: JSON.stringify(payload),
});View on GitHub (pinned to 49907e53dc)
Solutions
- Verify the vulnerability ID is correct and exists on https://osv.dev (search the ID on the website first)
- If the ID is a CVE alias, resolve it to the GHSA/OSV ID that OSV.dev actually indexes and retry
- Handle EmptyResultError in the caller and treat it as 'no data' rather than retrying
- Check the full URL built by osvGet for encoding mistakes (encodeURIComponent is applied to the id)
Example fix
// before
await osvGet(`${OSV_BASE}/v1/vulns/CVE-2023-123`, 'osv vulnerability CVE-2023-123');
// after
const vuln = await osvGet(`${OSV_BASE}/v1/vulns/ghsa-xxxx`, 'osv vulnerability ghsa-xxxx');
if (!vuln) console.log('No OSV record for that ID'); Defensive patterns
Strategy: try-catch
Validate before calling
if (!/^(CVE|GHSA|OSV|PYSEC|RSA|USN)-/i.test(id)) { throw new Error(`Suspicious vulnerability id: ${id}`); } Type guard
function hasOsvRecord(v) { return v != null && typeof v === 'object' && typeof v.id === 'string' && v.id.length > 0; } Try / catch
try {
const vuln = await vuln(id);
// use vuln
} catch (e) {
if (/404/.test(e.message)) return null; // no record
throw e;
} Prevention
- Validate vulnerability IDs against known prefixes (CVE-, GHSA-, OSV-, PYSEC-) before querying
- Resolve CVE aliases to OSV-canonical IDs before lookup
- Treat 404 as 'no data', not a crash, in batch scanning code
When it happens
Trigger: osvGet was called with a URL like `${OSV_BASE}/v1/vulns/<id>` (via the `vuln` command) and api.osv.dev responded with status 404 — typically a malformed or non-existent vulnerability ID passed through requireVulnId.
Common situations: Querying a CVE/GHSA/RSA ID that does not exist in OSV.dev or was aliased/withdrawn; a typo in the vulnerability ID; querying an ecosystem-specific ID OSV has never ingested.
Related errors
- Homebrew API returned 404 for ${url}.
- Lichess returned 404 for ${url}.
- ${label} returned 404 (no matches).
- OSV.dev returned no vulnerabilities for ${ecosystem}:${name}
- ${label} returned HTTP ${resp.status}${text ? `: ${text.slic
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/837f228784772fdb.
Report an issue: GitHub.