jackwener/OpenCLI · info · EmptyResultError

OSV.dev returned no vulnerabilities for ${ecosystem}:${name}

Error message

OSV.dev returned no vulnerabilities for ${ecosystem}:${name}${payload.version ? `@${payload.version}` : ''}.

What it means

The OSV.dev /v1/query API responded successfully but its `vulns` array was empty, meaning the database has no vulnerability records for that package (and version, when supplied). The adapter treats an empty result as an error condition via EmptyResultError so callers get a consistent signal instead of an empty list.

Source

Thrown at clis/osv/query.js:41

        { name: 'version', type: 'string', required: false, help: 'Pin to a specific version (e.g. "4.17.20"); omit for all known vulns' },
        { name: 'limit', type: 'int', default: 30, help: 'Max rows to return (1-200)' },
    ],
    columns: [
        'rank', 'id', 'summary', 'severity', 'aliases',
        'published', 'modified', 'affectedPackages', 'url',
    ],
    func: async (args) => {
        const name = requireString(args.package, 'package');
        const ecosystem = requireEcosystem(args.ecosystem);
        const limit = requireBoundedInt(args.limit, 30, 200, 'limit');
        const payload = { package: { name, ecosystem } };
        if (args.version != null && String(args.version).trim() !== '') {
            payload.version = String(args.version).trim();
        }
        const body = await osvPost(`${OSV_BASE}/v1/query`, payload, `osv query ${ecosystem}:${name}`);
        const vulns = Array.isArray(body?.vulns) ? body.vulns : [];
        if (vulns.length === 0) {
            throw new EmptyResultError(
                'osv query',
                `OSV.dev returned no vulnerabilities for ${ecosystem}:${name}${payload.version ? `@${payload.version}` : ''}.`,
            );
        }
        const sorted = vulns
            .slice()
            .sort((a, b) => String(b?.published ?? '').localeCompare(String(a?.published ?? '')))
            .slice(0, limit);
        return sorted.map((v, i) => {
            const affected = Array.isArray(v.affected) ? v.affected : [];
            const pkgPairs = [];
            for (const a of affected) {
                const eco = a?.package?.ecosystem;
                const aname = a?.package?.name;
                if (eco && aname) pkgPairs.push(`${eco}:${aname}`);
            }
            const aliases = Array.isArray(v.aliases) ? v.aliases.filter(Boolean) : [];
            return {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Verify the package name and ecosystem exactly match the registry spelling (case matters for some ecosystems).
  2. Drop the --version flag to check whether the package has any vulnerabilities at any version.
  3. Normalize the version string (strip leading 'v', use the exact registry version).
  4. If the package is private/new, it may legitimately have no records — treat empty as a clean result in your tooling.

Example fix

// before
await osvQuery({ ecosystem: 'npm', name: 'lodahs', version: 'v4.17.21' });
// after
await osvQuery({ ecosystem: 'npm', name: 'lodash', version: '4.17.21' });
Defensive patterns

Strategy: fallback

Validate before calling

if (!pkg || typeof pkg !== 'string' || !pkg.trim()) throw new Error('package name required before querying OSV');
if (pkg.startsWith('v')) pkg = pkg.slice(1);

Type guard

const isQueryPayload = (p) =>
  typeof p === 'object' && p !== null &&
  typeof p.ecosystem === 'string' && typeof p.name === 'string' && p.name.trim() !== '';

Try / catch

try {
  const vulns = await osvQuery({ ecosystem, name, version });
} catch (e) {
  if (e.name === 'EmptyResultError') {
    console.warn(`No known vulnerabilities for ${ecosystem}:${name} — treating as clean`);
    return [];
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling the osv query flow where POST /v1/query returns `{}` — e.g. a typo'd package name, an ecosystem/name mismatch, or a version that genuinely has no known vulnerabilities.

Common situations: Typo in package name; querying a private/unpublished package; passing a version string that doesn't match the registry (e.g. 'v1.2.3' vs '1.2.3'); the package is simply clean at that version.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/31e7dc6b0cfe1b13. Report an issue: GitHub.