jackwener/OpenCLI · error · ArgumentError
${label} must be a positive integer
Error message
${label} must be a positive integer What it means
normalizePositiveInteger validates that a numeric CLI option (bookRank, limit, fragmentSize) is a positive integer before use. The library throws ArgumentError when Number(value) is not an integer or is <= 0, i.e. the user passed a fractional, zero, negative, or non-numeric value for that option.
Source
Thrown at clis/weread/book-search.js:28
return String(value || '')
.replace(/<[^>]+>/g, '')
.replace(/&#x([0-9a-fA-F]+);/gi, (_, n) => String.fromCharCode(parseInt(n, 16)))
.replace(/&#(\d+);/g, (_, n) => String.fromCharCode(Number(n)))
.replace(/ /g, ' ')
.replace(/&/g, '&')
.replace(/"/g, '"')
.trim();
}
function normalizeSearchText(value) {
return String(value || '').replace(/\s+/g, ' ').trim();
}
function normalizePositiveInteger(value, defaultValue, label, maxValue) {
const raw = value ?? defaultValue;
const n = Number(raw);
if (!Number.isInteger(n) || n <= 0) {
throw new ArgumentError(`${label} must be a positive integer`);
}
if (maxValue != null && n > maxValue) {
throw new ArgumentError(`${label} must be <= ${maxValue}`);
}
return n;
}
function parseOptionalFiniteNumber(value) {
if (value == null || value === '')
return null;
const n = Number(value);
return Number.isFinite(n) ? n : null;
}
function parseHasMore(value) {
if (value === true || value === 1 || value === '1')
return true;
if (value === false || value === 0 || value === '0')View on GitHub (pinned to 49907e53dc)
Solutions
- Pass a whole number >= 1 for the offending option
- Omit the option entirely so the built-in defaultValue is used (null/undefined falls through via value ?? defaultValue)
- Fix the calling script so the variable holds a numeric string, e.g. LIMIT=20 not LIMIT=''
- Check the exact label in the message to see which option failed validation
Example fix
// before weread book-search --query zen --limit 0 // after weread book-search --query zen --limit 10
Defensive patterns
Strategy: validation
Validate before calling
function ensurePositiveInt(v, name) {
const n = Number(v);
if (!Number.isInteger(n) || n <= 0) throw new TypeError(`${name} must be a positive integer, got: ${JSON.stringify(v)}`);
return n;
}
ensurePositiveInt(opts.limit, 'limit'); Type guard
const isPositiveInt = (v) => Number.isInteger(Number(v)) && Number(v) > 0;
Try / catch
try {
await runCommand(['book-search', '--query', q, '--limit', String(limit)]);
} catch (e) {
if (e instanceof ArgumentError && e.message.includes('must be a positive integer')) {
console.error(`Bad numeric option: ${e.message}`); process.exitCode = 2;
} else throw e;
} Prevention
- Always coerce and validate numeric CLI inputs with Number.isInteger before passing them
- Default empty shell variables explicitly (LIMIT="${LIMIT:-10}") so '' never reaches the CLI
- Keep numeric values unquoted and free of units/spaces in scripts
When it happens
Trigger: Calling the book-search command with an option such as --book-rank, --limit, or --fragment-size set to 0, -1, 2.5, 'abc', an empty-but-non-null string, or a value that Number() coerces to NaN or Infinity.
Common situations: Users typo a flag value (--limit=ten), paste values with trailing spaces or units ('20 pages'), script variables are empty strings rather than unset (empty string coerces to 0), or shell interpolation yields a fractional number.
Related errors
- ${label} must be <= ${maxValue}
- archive search sort must be one of ${SORT_OPTIONS.join(', ')
- archive search mediatype must be one of ${MEDIATYPES.join(',
- archive search limit must be a positive integer
- archive search limit must be <= 100
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/fc577f95ea4a38e8.
Report an issue: GitHub.