jackwener/OpenCLI · error · ArgumentError

pubmed ${label} must be a positive integer

Error message

pubmed ${label} must be a positive integer

What it means

requireBoundedInt's first check: the value must be a string of digits only (/^\d+$/). Any signed, decimal, scientific-notation, or non-numeric value throws ArgumentError 'pubmed <label> must be a positive integer' (typically for the limit option).

Source

Thrown at clis/pubmed/utils.js:30

    if (!text) {
        throw new ArgumentError(`pubmed ${label} cannot be empty`);
    }
    return text;
}

export function requirePmid(value, label = 'pmid') {
    const pmid = requireText(value, label);
    if (!/^\d+$/.test(pmid)) {
        throw new ArgumentError(`pubmed ${label} must be a numeric PMID`, 'Example: 37780221');
    }
    return pmid;
}

export function requireBoundedInt(value, defaultValue, maxValue, label = 'limit') {
    const raw = value ?? defaultValue;
    const text = String(raw).trim();
    if (!/^\d+$/.test(text)) {
        throw new ArgumentError(`pubmed ${label} must be a positive integer`);
    }
    const n = Number(text);
    if (!Number.isSafeInteger(n) || n < 1) {
        throw new ArgumentError(`pubmed ${label} must be a positive integer`);
    }
    if (n > maxValue) {
        throw new ArgumentError(`pubmed ${label} must be <= ${maxValue}`);
    }
    return n;
}

export function requireYear(value, label) {
    if (value === undefined || value === null || value === '') {
        return undefined;
    }
    const year = requireBoundedInt(value, 1900, 3000, label);
    if (year < 1800) {
        throw new ArgumentError(`pubmed ${label} must be >= 1800`);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass a plain positive integer literal, e.g. `--limit 10`
  2. Remove signs, commas, units, or decimal points
  3. Stringify computed numbers without formatting in scripts

Example fix

// before
--limit 1,000
// after
--limit 1000
Defensive patterns

Strategy: validation

Validate before calling

const raw = String(limit ?? '').trim();
if (!/^\d+$/.test(raw)) {
  throw new Error(`limit must be a positive integer, got '${raw}'`);
}

Type guard

function isPositiveIntString(v) {
  return /^\d+$/.test(String(v ?? '').trim());
}

Try / catch

try {
  await cli.parse(['pubmed', 'search', query, '--limit', limitArg]);
} catch (err) {
  if (err instanceof ArgumentError && /positive integer/.test(err.message)) {
    console.error(`Bad --limit '${limitArg}'; use a plain integer like 10`);
    process.exitCode = 2;
  } else { throw err; }
}

Prevention

When it happens

Trigger: `--limit -1`, `--limit 3.5`, `--limit ten`, `--limit ''`, `--limit 1e3`, or values with separators like '1,000'.

Common situations: Numbers copied with thousands separators, units appended ('10 results'), negatives from loop counters, floats from other tools.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


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