jackwener/OpenCLI · warning · EmptyResultError
OSV.dev returned no record for "${id}".
Error message
OSV.dev returned no record for "${id}". What it means
The OSV vulnerability endpoint returned a 200 response whose body was empty or lacked an `id` field, so no usable record exists even though HTTP said OK. Thrown as EmptyResultError by the `vuln` command after osvGet succeeded.
Source
Thrown at clis/osv/vulnerability.js:29
site: 'osv',
name: 'vulnerability',
access: 'read',
description: 'Single OSV.dev vulnerability detail (severity, affected packages, CVE/GHSA aliases)',
domain: 'osv.dev',
strategy: Strategy.PUBLIC,
browser: false,
args: [
{ name: 'id', positional: true, type: 'string', required: true, help: 'OSV vulnerability id (e.g. "GHSA-29mw-wpgm-hmr9", "CVE-2020-28500")' },
],
columns: [
'id', 'summary', 'severity', 'aliases', 'published', 'modified',
'affectedPackages', 'cwes', 'referenceCount', 'url',
],
func: async (args) => {
const id = requireVulnId(args.id);
const vuln = await osvGet(`${OSV_BASE}/v1/vulns/${encodeURIComponent(id)}`, `osv vulnerability ${id}`);
if (!vuln || !vuln.id) {
throw new EmptyResultError('osv vulnerability', `OSV.dev returned no record for "${id}".`);
}
const affected = Array.isArray(vuln.affected) ? vuln.affected : [];
const pkgPairs = [];
for (const a of affected) {
const eco = a?.package?.ecosystem;
const name = a?.package?.name;
if (eco && name) pkgPairs.push(`${eco}:${name}`);
}
const aliases = Array.isArray(vuln.aliases) ? vuln.aliases.filter(Boolean) : [];
const cwes = Array.isArray(vuln?.database_specific?.cwe_ids) ? vuln.database_specific.cwe_ids : [];
const refs = Array.isArray(vuln.references) ? vuln.references : [];
return [{
id: String(vuln.id),
summary: String(vuln.summary ?? '').trim(),
severity: severityLabel(vuln),
aliases: aliases.join(', '),
published: trimDate(vuln.published),
modified: trimDate(vuln.modified),View on GitHub (pinned to 49907e53dc)
Solutions
- Confirm the ID resolves on https://osv.dev/vulnerability/<id> in a browser
- Try the alias ID (e.g. GHSA form of a CVE) — OSV sometimes serves records under the canonical ID only
- Handle EmptyResultError gracefully and fall back to another advisory source (NVD, GitHub Advisory DB)
- Check whether a proxy is corrupting the response body (200 with non-JSON content)
Example fix
// before
const v = await osvGet(`${OSV_BASE}/v1/vulns/${id}`, label); // may throw EmptyResultError
// after
try { return await fetchVuln(id); }
catch (e) {
if (e instanceof EmptyResultError) return fetchFromNvd(id);
throw e;
} Defensive patterns
Strategy: fallback
Validate before calling
if (!id || typeof id !== 'string' || !/^[A-Za-z]+-[A-Za-z0-9.-]+$/.test(id)) throw new Error(`Invalid vulnerability id: ${id}`); Type guard
function isOsvVuln(v) { return v != null && typeof v === 'object' && typeof v.id === 'string' && v.id.length > 0; } Try / catch
try {
const rec = await vuln(id);
return rec;
} catch (e) {
if (/no record/i.test(e.message)) return nvdLookup(id) ?? ghsaLookup(id) ?? null;
throw e;
} Prevention
- Prefer OSV-canonical IDs (GHSA/OSV) over alias IDs like CVE when known
- Fall back to NVD or GitHub Advisory DB when OSV has no record
- Verify uncertain IDs on osv.dev before batch lookups
- Treat empty-but-200 responses as 'no data', not corruption
When it happens
Trigger: `vuln` called osvGet on `/v1/vulns/<id>`; requireVulnId passed but the parsed JSON was null/empty or missing `id` — e.g. the ID exists as an alias only, or OSV returned an empty/degenerate document.
Common situations: Querying an ID that OSV knows only as an alias of another record; a withdrawn advisory served with an empty body; an intermediary (proxy/cache) returning 200 with an empty or HTML body instead of JSON.
Related errors
- OSV.dev returned no vulnerabilities for ${ecosystem}:${name}
- devto/${id}
- NO_DATA
- eastmoney convertible
- NO_DATA
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/28a5ba8927814969.
Report an issue: GitHub.