jackwener/OpenCLI · error · ArgumentError

nvd CVE id "${value}" is not a valid CVE identifier

Error message

nvd CVE id "${value}" is not a valid CVE identifier

What it means

This ArgumentError is thrown by requireCveId in clis/nvd/cve.js when a CVE id argument fails the regex /^CVE-\d{4}-\d{4,}$/i after trimming and uppercasing. The library requires the canonical NVD form "CVE-YYYY-N..." with a 4-digit year and at least 4 sequence digits. It is a client-side input guard so malformed ids never reach the NVD API.

Source

Thrown at clis/nvd/cve.js:18

// nvd cve — fetch a single CVE from the NIST National Vulnerability Database.
//
// Hits the CVE API 2.0 (`services.nvd.nist.gov/rest/json/cves/2.0?cveId=…`).
// Returns the agent-useful projection: id, published / last-modified dates,
// vuln status, English description, CVSS v3.1 base score / severity / vector,
// CWE id(s), CISA KEV flag.
import { cli, Strategy } from '@jackwener/opencli/registry';
import { ArgumentError, CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';

const NVD_BASE = 'https://services.nvd.nist.gov/rest/json/cves/2.0';
const UA = 'opencli-nvd-adapter (+https://github.com/jackwener/opencli)';
const CVE_ID = /^CVE-\d{4}-\d{4,}$/i;

function requireCveId(value) {
    const s = String(value ?? '').trim().toUpperCase();
    if (!s) throw new ArgumentError('nvd CVE id is required (e.g. "CVE-2021-44228")');
    if (!CVE_ID.test(s)) {
        throw new ArgumentError(
            `nvd CVE id "${value}" is not a valid CVE identifier`,
            'Expected the form "CVE-YYYY-N..." with at least 4 sequence digits.',
        );
    }
    return s;
}

function pickEnglishDescription(descriptions) {
    if (!Array.isArray(descriptions)) return '';
    const en = descriptions.find((d) => d?.lang === 'en');
    return String(en?.value ?? descriptions[0]?.value ?? '').trim();
}

function pickPrimaryCvss(metrics) {
    if (!metrics || typeof metrics !== 'object') return null;
    const candidates = [
        ...(Array.isArray(metrics.cvssMetricV31) ? metrics.cvssMetricV31 : []),
        ...(Array.isArray(metrics.cvssMetricV30) ? metrics.cvssMetricV30 : []),

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Reformat the id as CVE-YYYY-N with the full year and at least 4 sequence digits, e.g. CVE-2021-44228.
  2. Strip surrounding text/quotes and trim whitespace before passing the value.
  3. Validate locally with /^CVE-\d{4}-\d{4,}$/i before calling the command.
  4. If only a sequence number is known, look up the year it was assigned (or use NVD keyword search instead of cveId lookup).

Example fix

// before
nvd cve "log4shell"
// after
nvd cve "CVE-2021-44228"
Defensive patterns

Strategy: validation

Validate before calling

const CVE_ID = /^CVE-\d{4}-\d{4,}$/i;
const id = String(raw ?? '').trim().toUpperCase();
if (!CVE_ID.test(id)) throw new Error(`invalid CVE id: ${raw}`);

Type guard

const isCveId = (v) => typeof v === 'string' && /^CVE-\d{4}-\d{4,}$/i.test(v.trim());

Try / catch

try { const id = requireCveId(raw); } catch (e) { if (e instanceof ArgumentError) { console.error('Usage: cve CVE-YYYY-NNNN'); } else { throw e; } }

Prevention

When it happens

Trigger: Calling id() (via requireCveId) with values like "2021-44228", "CVE-21-44228", "cve-2021-123" (only 3 sequence digits), "CVE-2021-44228 ", or an empty/null argument (that hits the separate empty-id error but the same function).

Common situations: Users paste CVE ids with extra prose ("CVE-2021-44228 (Log4Shell)"), omit the "CVE-" prefix, use short forms seen in changelogs, or pass a shell variable that is empty or contains a URL fragment.

Related errors


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