jackwener/OpenCLI · error · ArgumentError
openalex ${label} must be a positive integer
Error message
openalex ${label} must be a positive integer What it means
requireBoundedInt validates that a numeric argument (default label 'limit') is a positive integer and throws ArgumentError when it is zero, negative, fractional, or non-numeric. This guards the OpenAlex `per-page` parameter, which requires an integer >= 1. Non-integer numeric strings like '3.5' or 'abc' also fail because Number() coercion yields a non-integer or NaN.
Source
Thrown at clis/openalex/utils.js:30
// OpenAlex stable IDs: a single-letter prefix (`W` works, `A` authors, `S`
// sources, `I` institutions…) + at least 4 digits. We accept just `W` here.
const WORK_ID = /^W\d{4,}$/;
// DOIs are loose — accept anything starting with "10." after the optional
// `doi.org/` prefix; OpenAlex itself does the normalization.
const DOI_BARE = /^10\.\S+$/;
export function requireString(value, label) {
const s = String(value ?? '').trim();
if (!s) throw new ArgumentError(`openalex ${label} cannot be empty`);
return s;
}
export function requireBoundedInt(value, defaultValue, maxValue, label = 'limit') {
const raw = value ?? defaultValue;
const n = typeof raw === 'number' ? raw : Number(raw);
if (!Number.isInteger(n) || n <= 0) {
throw new ArgumentError(`openalex ${label} must be a positive integer`);
}
if (n > maxValue) {
throw new ArgumentError(`openalex ${label} must be <= ${maxValue}`);
}
return n;
}
/**
* Resolve a user-supplied work identifier to OpenAlex's canonical path
* segment. Accepts `W…` IDs, `doi:10.…`, raw DOIs, or full
* `https://doi.org/…` / `https://openalex.org/W…` URLs.
*/
export function requireWorkRef(value) {
const raw = String(value ?? '').trim();
if (!raw) {
throw new ArgumentError('openalex work id is required (e.g. "W2741809807", "10.7717/peerj.4375")');
}
// 1) full openalex URLView on GitHub (pinned to 49907e53dc)
Solutions
- Pass a whole number >= 1 for limit (or omit it to use the default)
- Coerce/validate the value with Number.isInteger before calling
- Check the upstream variable isn't 0, NaN, or a string with stray characters
Example fix
// before
await search({ query, limit: 0 });
// after
await search({ query, limit: 25 }); Defensive patterns
Strategy: validation
Validate before calling
function parseLimit(raw, max = 200) {
const n = typeof raw === 'number' ? raw : Number(raw);
if (!Number.isInteger(n) || n <= 0) throw new Error(`limit must be a positive integer, got ${raw}`);
return Math.min(n, max);
} Type guard
function isPositiveInt(v) {
return typeof v === 'number' && Number.isInteger(v) && v > 0;
} Try / catch
try {
await search({ query, limit });
} catch (e) {
if (e.name === 'ArgumentError' && e.message.includes('positive integer')) {
console.error('limit must be a whole number >= 1'); process.exitCode = 2;
} else throw e;
} Prevention
- Coerce CLI flags with Number() and check Number.isInteger before calling
- Never pass 0 expecting 'unlimited' — omit limit to use the default
- Watch for 'NaN' leaking from upstream variables
When it happens
Trigger: Calling a command with `limit` set to 0, a negative number, a decimal like 2.5, or a non-numeric string such as 'ten' or '10abc' (Number('10abc') is NaN).
Common situations: Passing `--limit 0` expecting 'unlimited'; copy-pasting a value with a trailing character; a script emitting 'NaN' or 'undefined' into the flag; misunderstanding that limit is 1-based and required.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- openalex ${label} must be <= ${maxValue}
- openalex ${label} cannot be empty
- openalex work id is required (e.g. "W2741809807", "10.7717/p
- openalex work id "${value}" must be a Work (W…) ID, got "${i
- openalex work id "${value}" is not recognised
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/3bae92783524e104.
Report an issue: GitHub.