jackwener/OpenCLI · error · ArgumentError

${label} must be <= ${maxValue}

Error message

${label} must be <= ${maxValue}

What it means

normalizePositiveInteger also enforces an optional upper bound (maxValue); if the parsed integer exceeds it, the library throws ArgumentError with the label and the max. This guards options like limit or fragment-size against absurd values that would break downstream requests or pagination.

Source

Thrown at clis/weread/book-search.js:31

        .replace(/&#(\d+);/g, (_, n) => String.fromCharCode(Number(n)))
        .replace(/&nbsp;/g, ' ')
        .replace(/&amp;/g, '&')
        .replace(/&quot;/g, '"')
        .trim();
}

function normalizeSearchText(value) {
    return String(value || '').replace(/\s+/g, ' ').trim();
}

function normalizePositiveInteger(value, defaultValue, label, maxValue) {
    const raw = value ?? defaultValue;
    const n = Number(raw);
    if (!Number.isInteger(n) || n <= 0) {
        throw new ArgumentError(`${label} must be a positive integer`);
    }
    if (maxValue != null && n > maxValue) {
        throw new ArgumentError(`${label} must be <= ${maxValue}`);
    }
    return n;
}

function parseOptionalFiniteNumber(value) {
    if (value == null || value === '')
        return null;
    const n = Number(value);
    return Number.isFinite(n) ? n : null;
}

function parseHasMore(value) {
    if (value === true || value === 1 || value === '1')
        return true;
    if (value === false || value === 0 || value === '0')
        return false;
    return null;
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Lower the option value to at most the stated maxValue in the message
  2. Check the command help/default to learn the allowed maximum
  3. Clamp the value in the calling script: Math.min(value, MAX)
  4. If the cap seems too restrictive, open an issue or patch normalizePositiveInteger's call site instead of fighting it at runtime

Example fix

// before
weread book-search --query zen --limit 500
// after
weread book-search --query zen --limit 20
Defensive patterns

Strategy: validation

Validate before calling

function ensureInRange(v, name, max) {
  const n = ensurePositiveInt(v, name);
  if (max != null && n > max) throw new RangeError(`${name} must be <= ${max}, got ${n}`);
  return n;
}
ensureInRange(opts.limit, 'limit', 50);

Type guard

const withinMax = (v, max) => Number.isInteger(Number(v)) && Number(v) > 0 && Number(v) <= max;

Try / catch

try {
  await runCommand(['book-search', '--query', q, '--limit', String(limit)]);
} catch (e) {
  if (e instanceof ArgumentError && /must be <= /.test(e.message)) {
    const max = Number(e.message.match(/<= (\d+)/)?.[1] ?? Infinity);
    console.error(`Reduce the option to at most ${max}.`);
  } else throw e;
}

Prevention

When it happens

Trigger: Passing --limit 1000 or --fragment-size 99999 when the command's normalizePositiveInteger call passes a maxValue cap, or --book-rank greater than the allowed maximum configured by the command.

Common situations: Users assume 'bigger is better' for limits; copy-pasted settings from another tool exceed this tool's caps; scripts use hardcoded large batch sizes.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/76d5706aa12617b7. Report an issue: GitHub.