{"record":{"id":"837f228784772fdb","repo":"jackwener/OpenCLI","slug":"osv-dev-returned-404-for-url","errorCode":null,"errorMessage":"OSV.dev returned 404 for ${url}.","messagePattern":"OSV\\.dev returned 404 for (.+?)\\.","errorType":"exception","errorClass":"EmptyResultError","httpStatus":404,"severity":"warning","filePath":"clis/osv/utils.js","lineNumber":109,"sourceCode":"    catch (err) {\n        throw new CommandExecutionError(`${label} returned malformed JSON: ${err?.message ?? err}`);\n    }\n    return body;\n}\n\nexport async function osvGet(url, label) {\n    let resp;\n    try {\n        resp = await fetch(url, { headers: { 'user-agent': UA, accept: 'application/json' } });\n    }\n    catch (err) {\n        throw new CommandExecutionError(\n            `${label} request failed: ${err?.message ?? err}`,\n            'Check that api.osv.dev is reachable from this network.',\n        );\n    }\n    if (resp.status === 404) {\n        throw new EmptyResultError(label, `OSV.dev returned 404 for ${url}.`);\n    }\n    if (resp.status === 429) {\n        throw new CommandExecutionError(`${label} returned HTTP 429 (rate limited)`);\n    }\n    if (!resp.ok) {\n        throw new CommandExecutionError(`${label} returned HTTP ${resp.status}`);\n    }\n    return readJson(resp, label);\n}\n\nexport async function osvPost(url, payload, label) {\n    let resp;\n    try {\n        resp = await fetch(url, {\n            method: 'POST',\n            headers: { 'user-agent': UA, accept: 'application/json', 'content-type': 'application/json' },\n            body: JSON.stringify(payload),\n        });","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/osv/utils.js#L91-L127","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":"// before\nawait osvGet(`${OSV_BASE}/v1/vulns/CVE-2023-123`, 'osv vulnerability CVE-2023-123');\n// after\nconst vuln = await osvGet(`${OSV_BASE}/v1/vulns/ghsa-xxxx`, 'osv vulnerability ghsa-xxxx');\nif (!vuln) console.log('No OSV record for that ID');","handlingStrategy":"try-catch","validationCode":"if (!/^(CVE|GHSA|OSV|PYSEC|RSA|USN)-/i.test(id)) { throw new Error(`Suspicious vulnerability id: ${id}`); }","typeGuard":"function hasOsvRecord(v) { return v != null && typeof v === 'object' && typeof v.id === 'string' && v.id.length > 0; }","tryCatchPattern":"try {\n  const vuln = await vuln(id);\n  // use vuln\n} catch (e) {\n  if (/404/.test(e.message)) return null; // no record\n  throw e;\n}","preventionTips":["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"],"tags":["http-404","api","osv"],"backgroundTag":"http-404-not-found","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}