jackwener/OpenCLI · error · ArgumentError
${label} must be a positive integer
Error message
${label} must be a positive integer What it means
ArgumentError thrown by normalizePositiveInt in clis/midjourney/utils.js when a numeric option (e.g. --timeout, --limit) is not an integer >= 1, or exceeds its maximum. The helper applies a fallback when the value is null/empty, otherwise coerces with Number() and validates Number.isInteger(parsed) && parsed >= 1, then enforces parsed <= max.
Source
Thrown at clis/midjourney/utils.js:53
export function unwrapEvaluateResult(payload) {
if (payload && !Array.isArray(payload) && typeof payload === 'object' && 'session' in payload && 'data' in payload) {
return payload.data;
}
return payload;
}
export function normalizeBoolean(value, fallback = false) {
if (typeof value === 'boolean') return value;
if (value == null || value === '') return fallback;
const normalized = String(value).trim().toLowerCase();
return ['true', '1', 'yes', 'on'].includes(normalized);
}
export function normalizePositiveInt(value, fallback, max, label) {
const parsed = value == null || value === '' ? fallback : Number(value);
if (!Number.isInteger(parsed) || parsed < 1) {
throw new ArgumentError(`${label} must be a positive integer`);
}
if (parsed > max) {
throw new ArgumentError(`${label} must be <= ${max}`);
}
return parsed;
}
export function parseJobId(value) {
const raw = String(value ?? '').trim();
if (UUID_RE.test(raw)) return raw.toLowerCase();
try {
const parsed = new URL(raw);
const match = parsed.pathname.match(/^\/jobs\/([0-9a-f-]{36})\/?$/i);
if (parsed.protocol === 'https:' && parsed.hostname === MIDJOURNEY_DOMAIN && match && UUID_RE.test(match[1])) {
return match[1].toLowerCase();
}
} catch {}
throw new ArgumentError(View on GitHub (pinned to 49907e53dc)
Solutions
- Pass a whole number >= 1 and within the max: --timeout 1..900, --limit 1..100.
- Quote/validate shell variables: use "${LIMIT:-10}" and check it's a positive integer before invoking.
- Remove the flag entirely to use the built-in default (timeout 300, limit 10) instead of passing 0 or empty.
- Check the command's --help for each numeric argument's documented range.
Example fix
// before opencli midjourney history --limit 0 // after opencli midjourney history --limit 25 # or omit the flag for the default (10): opencli midjourney history
Defensive patterns
Strategy: validation
Validate before calling
function toPositiveInt(value, { max, fallback, label }) {
if (value == null || value === '') return fallback;
const n = Number(value);
if (!Number.isInteger(n) || n < 1) throw new Error(`${label} must be a positive integer (got "${value}")`);
if (max != null && n > max) throw new Error(`${label} must be <= ${max}`);
return n;
}
const limit = toPositiveInt(process.env.MJ_LIMIT, { max: 100, fallback: 10, label: '--limit' });
const timeout = toPositiveInt(process.env.MJ_TIMEOUT, { max: 900, fallback: 300, label: '--timeout' }); Type guard
function isPositiveInt(v) { return Number.isInteger(v) && v >= 1; } Try / catch
import { ArgumentError } from '@jackwener/opencli/errors';
try {
await opencli.midjourney.history({ limit });
} catch (e) {
if (e instanceof ArgumentError && /positive integer|must be <=/.test(e.message)) {
console.error(`Bad option: ${e.message}`); process.exitCode = 2; return;
}
throw e;
} Prevention
- Coerce and validate numeric CLI/env inputs with Number() + Number.isInteger before passing them.
- Remember the documented caps: --timeout 1..900, --limit 1..100.
- Handle empty shell variables explicitly ("${VAR:-default}") so blank expansions don't become '0' or garbage.
- Never pass fractional or zero values — omit the flag to get the built-in default instead.
When it happens
Trigger: `opencli midjourney login --timeout 0` or `--timeout -5`; `opencli midjourney history --limit 2.5` (non-integer); `--limit abc` (NaN fails Number.isInteger); passing a value above the per-arg max, e.g. --timeout 1000 (>900) or --limit 500 (>100).
Common situations: Shell variables that are empty strings expanded into flags; copy-pasting limits from docs of other tools; decimal typing ('1.5 minutes'); forgetting the documented cap (timeout 1..900, limit 1..100); passing '--limit ""' which falls back correctly but '--limit 0' fails.
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
- lobsters limit must be a positive integer
- 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/aacee1bed607c05a.
Report an issue: GitHub.