jackwener/OpenCLI · error · ArgumentError
Argument "${argDef.name}" must be a valid integer. Received:
Error message
Argument "${argDef.name}" must be a valid integer. Received: "${val}" What it means
For arguments typed 'int', coerceAndValidateArgs requires the numeric value to be a whole number. After the finite-number check passes, a non-integer value (e.g. 2.5) throws ArgumentError stating the argument must be a valid integer.
Source
Thrown at src/execution.ts:74
for (const argDef of cmdArgs) {
const val = result[argDef.name];
if (argDef.required && (val === undefined || val === null || val === '')) {
throw new ArgumentError(
`Argument "${argDef.name}" is required.`,
argDef.help ?? `Provide a value for --${argDef.name}`,
);
}
if (val !== undefined && val !== null) {
if (argDef.type === 'int' || argDef.type === 'number') {
const num = Number(val);
if (!Number.isFinite(num)) {
throw new ArgumentError(`Argument "${argDef.name}" must be a valid number. Received: "${val}"`);
}
if (argDef.type === 'int' && !Number.isInteger(num)) {
throw new ArgumentError(`Argument "${argDef.name}" must be a valid integer. Received: "${val}"`);
}
result[argDef.name] = num;
} else if (argDef.type === 'boolean' || argDef.type === 'bool') {
if (typeof val === 'string') {
const lower = val.toLowerCase();
if (lower === 'true' || lower === '1') result[argDef.name] = true;
else if (lower === 'false' || lower === '0') result[argDef.name] = false;
else throw new ArgumentError(`Argument "${argDef.name}" must be a boolean (true/false). Received: "${val}"`);
} else {
result[argDef.name] = Boolean(val);
}
}
const coercedVal = result[argDef.name];
if (argDef.choices && argDef.choices.length > 0) {
if (!argDef.choices.map(String).includes(String(coercedVal))) {
throw new ArgumentError(`Argument "${argDef.name}" must be one of: ${argDef.choices.join(', ')}. Received: "${coercedVal}"`);
}View on GitHub (pinned to 49907e53dc)
Solutions
- Pass a whole number, e.g. --workers 3.
- Round/ceil the computed value in the calling script (Math.ceil(x)) before passing.
- If fractional values are legitimate, check whether the argument should be typed 'number' instead of 'int' (library-side change).
Example fix
// before opencli run --workers $((total / 2)) # 2.5 // after opencli run --workers $(( (total + 1) / 2 )) # integer
Defensive patterns
Strategy: validation
Validate before calling
function toInt(v: unknown, label: string): number {
const n = Number(v);
if (!Number.isFinite(n) || !Number.isInteger(n)) throw new Error(`${label} must be an integer, got: ${String(v)}`);
return n;
}
kwargs.workers = toInt(kwargs.workers, '--workers'); Type guard
const isInt = (v: unknown): v is number => typeof v === 'number' && Number.isInteger(v);
Try / catch
try {
await opencli.run(cmd, kwargs);
} catch (e) {
if (/must be a valid integer/.test(e.message)) {
console.error(`${e.message} — round the value before passing (Math.ceil/Math.floor).`);
} else throw e;
} Prevention
- Round results of division before passing them to int-typed flags.
- Never pass fractional counts like 0.5 or 2.5.
- Use Math.ceil/floor explicitly in scripts that compute counts.
When it happens
Trigger: Passing --workers 2.5, --retries 1.0 with a decimal representation via kwargs (number 1.5), or any fractional value to an int-typed flag.
Common situations: Dividing a total by a count in scripts (total/2) producing fractions; percentages passed as 0.5 where an integer count is expected; defaults copied from float-based configs.
Related errors
- juejin ${label} must be a positive decimal integer
- juejin ${label} must be a positive integer
- --limit must be an integer between ${MIN_LIMIT} and ${MAX_LI
- Argument "${argDef.name}" must be a valid number. Received:
- Argument "${argDef.name}" must be a boolean (true/false). Re
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/2334b7d3add3be01.
Report an issue: GitHub.