jackwener/OpenCLI · error · ArgumentError
crates ${label} must be a positive integer
Error message
crates ${label} must be a positive integer What it means
requireBoundedInt coerces its argument to a number and requires a positive integer before applying the upper bound. Non-integer, zero, negative, or NaN values throw this ArgumentError ('crates limit must be a positive integer'). The adapter fails fast rather than clamping, so callers know their value was not silently rewritten.
Source
Thrown at clis/crates/utils.js:32
}
export function requireCrateName(value) {
const s = String(value ?? '').trim();
if (!s) throw new ArgumentError('crates crate name is required (e.g. "serde", "tokio")');
if (!CRATE_NAME.test(s)) {
throw new ArgumentError(
`crates crate name "${value}" is not a valid crates.io name`,
'Names start with an ASCII letter, then 0-63 chars of letters / digits / "_-".',
);
}
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(`crates ${label} must be a positive integer`);
}
if (n > maxValue) {
throw new ArgumentError(`crates ${label} must be <= ${maxValue}`);
}
return n;
}
export async function cratesFetch(url, label) {
let resp;
try {
// crates.io requires a descriptive User-Agent per https://crates.io/data-access
resp = await fetch(url, { headers: { 'user-agent': UA, accept: 'application/json' } });
}
catch (err) {
throw new CommandExecutionError(
`${label} request failed: ${err?.message ?? err}`,
'Check that crates.io is reachable from this network.',
);View on GitHub (pinned to 49907e53dc)
Solutions
- Pass a positive integer, e.g. --limit 20.
- Omit the flag entirely to use the default (20).
- Parse/validate user input before passing: Number.isInteger(n) && n > 0.
- If you want 'no limit', use the maximum allowed value (see the <= bound error) rather than 0.
Example fix
// before
await cli.crates.search({ query: 'web', limit: 'all' });
// after
await cli.crates.search({ query: 'web', limit: 50 }); // or omit limit for default 20 Defensive patterns
Strategy: validation
Validate before calling
function parseLimit(raw, fallback = 20) {
if (raw === undefined || raw === null || raw === '') return fallback;
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 n;
} Type guard
function isPositiveInt(v) {
return typeof v === 'number' && Number.isInteger(v) && v > 0;
} Try / catch
try {
await cli.crates.search({ query, limit });
} catch (e) {
if (e instanceof ArgumentError && e.message.includes('must be a positive integer')) {
console.error('limit must be an integer >= 1; using default 20.');
return cli.crates.search({ query });
}
throw e;
} Prevention
- Coerce with Number() and check Number.isInteger before passing user input.
- Treat 0/negative as invalid, not as 'unlimited'.
- Omit the flag to use the built-in default instead of inventing sentinel values.
- Reject numeric strings with units or separators at your CLI boundary.
When it happens
Trigger: Calling `crates search` with --limit 0, -5, 'abc', 2.5, or '' (empty string coerces to NaN); passing a numeric string with units like '20 items'; passing true/false (coerce to 1/0).
Common situations: Hand-editing scripts with an invalid limit, shell flags receiving an empty value, config files holding '0' to mean 'no limit' (not supported), or locale-formatted numbers with commas.
Related errors
- crates ${label} cannot be empty
- crates crate name is required (e.g. "serde", "tokio")
- crates crate name "${value}" is not a valid crates.io name
- crates ${label} must be <= ${maxValue}
- <train-no> must not be empty
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/1dfd48a0d8972eec.
Report an issue: GitHub.