jackwener/OpenCLI · error · ArgumentError

${name} must be${suffix} (got "${raw}")

Error message

${name} must be${suffix} (got "${raw}")

What it means

parsePositiveInteger validates a CLI numeric option and throws ArgumentError when the parsed value is not a strictly positive integer or exceeds the configured `max`. The message names the option, the allowed range, and echoes the raw input. It is the shared numeric-argument gate used by `limit` and `number` style options.

Source

Thrown at clis/slock/resolve.js:53

const SHORT_ID_HINT =
  'short ids (the 8-hex `msg=...` form in channel headers) are NOT accepted — use the FULL UUID ' +
  'from `bookmark-list` / `message-read` output.';

export function assertMessageIdShape(messageId) {
  const v = String(messageId ?? '').trim();
  if (!v) throw new ArgumentError('messageId required');
  if (!UUID_RE.test(v)) {
    throw new ArgumentError(`messageId "${v}" is not a full UUID. ${SHORT_ID_HINT}`);
  }
  return v;
}

export function parsePositiveInteger(value, name, { defaultValue, max } = {}) {
  const raw = value === undefined || value === null || value === '' ? defaultValue : value;
  const n = parseStrictInteger(raw);
  if (!Number.isInteger(n) || n <= 0 || (max !== undefined && n > max)) {
    const suffix = max !== undefined ? ` between 1 and ${max}` : ' as a positive integer';
    throw new ArgumentError(`${name} must be${suffix} (got "${raw}")`);
  }
  return n;
}

export function parseNonNegativeInteger(value, name, { defaultValue } = {}) {
  const raw = value === undefined || value === null || value === '' ? defaultValue : value;
  const n = parseStrictInteger(raw);
  if (!Number.isInteger(n) || n < 0) {
    throw new ArgumentError(`${name} must be a non-negative integer (got "${raw}")`);
  }
  return n;
}

function parseStrictInteger(raw) {
  if (typeof raw === 'number')
    return raw;
  const text = String(raw);
  if (!/^\d+$/.test(text))

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass a whole number >= 1 that does not exceed the option's documented max.
  2. Omit the option entirely so the built-in defaultValue is used.
  3. If you control the code, widen validation by using parseNonNegativeInteger or lowering the max constraint as appropriate.

Example fix

// before
await cli('slock', 'task-list', '--limit', '2.5');
// after
await cli('slock', 'task-list', '--limit', '25');
Defensive patterns

Strategy: validation

Validate before calling

function isValidPositiveInt(v, max) {
  const n = Number(v);
  return Number.isInteger(n) && n >= 1 && (max === undefined || n <= max);
}
if (!isValidPositiveInt(limit, 100)) throw new Error('limit must be an integer 1..100');

Type guard

const isPositiveInt = (v) => typeof v === 'number' && Number.isInteger(v) && v > 0;

Try / catch

try {
  runCommand(['--limit', String(raw)]);
} catch (e) {
  if (e instanceof ArgumentError && e.message.includes('must be')) {
    console.error(`Bad --limit value "${raw}": ${e.message}`);
    process.exitCode = 2;
  } else throw e;
}

Prevention

When it happens

Trigger: Calling a CLI command with a limit/number option set to a non-integer (e.g. '3.5', 'abc'), zero, a negative number, or a value above the max passed in options (e.g. --limit 500 when max=100).

Common situations: Typing `--limit 0` expecting 'unlimited'; pasting a float like `--limit 2.5`; exceeding an API-imposed page-size cap; shell interpolation substituting an empty or garbage value into the flag.

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


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