jackwener/OpenCLI · error · ArgumentError
rest-countries ${label} must be a positive integer
Error message
rest-countries ${label} must be a positive integer What it means
requireBoundedInt coerces its input to a number and throws ArgumentError if the result is not a positive integer. This catches NaN, floats, zero, negatives, and non-numeric strings. It exists so the limit argument is always a sane count before building API requests.
Source
Thrown at clis/rest-countries/utils.js:32
// Fields the adapter always requests; keep this list aligned with `columns` so
// rows never have null-where-absent silent drops.
export const COUNTRY_FIELDS = [
'name', 'cca2', 'cca3', 'ccn3', 'capital', 'region', 'subregion',
'population', 'area', 'languages', 'currencies', 'flag', 'latlng', 'timezones',
'independent', 'unMember', 'landlocked',
].join(',');
export function requireString(value, label) {
const s = String(value ?? '').trim();
if (!s) throw new ArgumentError(`rest-countries ${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(`rest-countries ${label} must be a positive integer`);
}
if (n > maxValue) {
throw new ArgumentError(`rest-countries ${label} must be <= ${maxValue}`);
}
return n;
}
export function requireRegion(value) {
const raw = String(value ?? '').trim().toLowerCase();
if (!raw) throw new ArgumentError('rest-countries region is required (e.g. "europe", "asia")');
if (!REST_COUNTRIES_REGIONS.has(raw)) {
throw new ArgumentError(
`rest-countries region "${value}" is not recognised`,
`Allowed regions: ${[...REST_COUNTRIES_REGIONS].join(', ')}.`,
);
}
return raw;
}View on GitHub (pinned to 49907e53dc)
Solutions
- Pass limit as a positive whole number (>= 1).
- Coerce and validate the value (Number.isInteger) before calling the command.
- Omit limit to use the command's default.
- Catch ArgumentError and re-prompt or fall back to the default.
Example fix
// before
await countryCommand({ name: 'france', limit: 'ten' });
// after
await countryCommand({ name: 'france', limit: 10 }); Defensive patterns
Strategy: validation
Validate before calling
const n = Number(rawLimit);
if (!Number.isInteger(n) || n <= 0) {
throw new TypeError('limit must be a positive integer');
} Type guard
function isPositiveInt(v) {
const n = typeof v === 'number' ? v : Number(v);
return Number.isInteger(n) && n > 0;
} Try / catch
try {
await countryCommand({ name, limit: rawLimit });
} catch (err) {
if (err instanceof ArgumentError && /positive integer/.test(err.message)) {
return countryCommand({ name }); // fall back to default limit
}
throw err;
} Prevention
- Parse CLI numeric flags with an explicit coercion + Number.isInteger check.
- Reject empty strings early — Number('') is 0 and will fail.
- Prefer omitting limit to using the default rather than guessing values.
- Cover argument coercion with unit tests.
When it happens
Trigger: Passing limit values like 0, -5, 'abc', 2.5, or '' to a rest-countries command so `Number.isInteger(n) || n <= 0` fails at clis/rest-countries/utils.js:32.
Common situations: User typing a non-numeric CLI flag value; a config file containing '25 countries'; floating-point math producing a fractional limit; empty string from an unset env var.
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
- ${label} must be an integer between ${min} and ${max}, got $
- 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/cdf8ec7a6d35bc62.
Report an issue: GitHub.