jackwener/OpenCLI · error · ArgumentError
${label} must be a positive integer
Error message
${label} must be a positive integer What it means
normalizePositiveInt coerces its input with Number() and requires the result to be an integer strictly greater than 0 (optionally capped by max). This ArgumentError is thrown when the caller passes a value that is missing-and-has-no-default, non-numeric, fractional, negative, or zero for an option labeled by `label` (e.g. adults, rooms, limit). It is an input-validation guard so the booking search CLI never runs with nonsensical counts.
Source
Thrown at clis/booking/search.js:14
import {
ArgumentError,
CommandExecutionError,
EmptyResultError,
} from '@jackwener/opencli/errors';
import { cli, Strategy } from '@jackwener/opencli/registry';
const DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
function normalizePositiveInt(value, defaultValue, label, max) {
const raw = value ?? defaultValue;
const n = Number(raw);
if (!Number.isInteger(n) || n <= 0) {
throw new ArgumentError(`${label} must be a positive integer`);
}
if (typeof max === 'number' && n > max) {
throw new ArgumentError(`${label} must be <= ${max}`);
}
return n;
}
function normalizeNonNegativeInt(value, defaultValue, label, max) {
const raw = value ?? defaultValue;
const n = Number(raw);
if (!Number.isInteger(n) || n < 0) {
throw new ArgumentError(`${label} must be a non-negative integer`);
}
if (typeof max === 'number' && n > max) {
throw new ArgumentError(`${label} must be <= ${max}`);
}
return n;
}View on GitHub (pinned to 49907e53dc)
Solutions
- Pass a positive integer (>= 1) for the flagged option, e.g. --adults 2.
- If the value comes from user input, parse and validate it first: Number.parseInt + Number.isInteger + n > 0.
- Omit the option entirely so the built-in defaultValue applies (value ?? defaultValue), instead of explicitly passing null/0.
- Check the error message's `label` to identify exactly which option was invalid and re-run only fixing that one.
Example fix
// before
await bookingSearch({ adults: 0, rooms: 1 });
// throws: adults must be a positive integer
// after
await bookingSearch({ adults: 2, rooms: 1 }); Defensive patterns
Strategy: validation
Validate before calling
function assertPositiveInt(value, label, max) {
const n = Number(value);
if (!Number.isInteger(n) || n <= 0) throw new Error(`${label} must be a positive integer`);
if (typeof max === 'number' && n > max) throw new Error(`${label} must be <= ${max}`);
return n;
}
const adults = assertPositiveInt(opts.adults ?? 2, 'adults', 16); Type guard
function isPositiveInt(v) {
return typeof v === 'number' && Number.isInteger(v) && v > 0;
} Try / catch
try {
await bookingSearch({ adults, rooms, 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
- Coerce CLI strings with Number.parseInt(str, 10) and check Number.isInteger before calling.
- Never pass sentinel values like 0 or -1; omit the option to use the default.
- Share one validation helper across all count options.
- Trim/strip units from user input before Number().
When it happens
Trigger: Calling the search command with adults/rooms/limit set to values like 0, -1, 'two', 2.5, '', NaN, or null when no defaultValue applies. Also passing numeric strings with whitespace/units like '2 people', since Number('2 people') is NaN.
Common situations: Users typing `--adults 0` or `--limit -5`; config files exporting strings like 'undefined'; programmatically passing a variable that is undefined where the option had no default; parsing user input without trimming; locale-formatted numbers ('2,5').
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
- ${label} must be a non-negative integer, got ${JSON.stringif
- limit must be a positive integer
- bilibili comment ${label} must be a positive integer
- bilibili comment message cannot be empty
- bilibili unfollow target cannot be empty
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/6db57b51861f78cf.
Report an issue: GitHub.