jackwener/OpenCLI · error · ArgumentError

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

Error message

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

What it means

After confirming the value is a positive integer, normalizePositiveInt checks it against an optional `max` bound. This ArgumentError is thrown when a valid integer exceeds the documented upper limit for that option (e.g. adults > 16, rooms > 8, limit > some cap). It exists to keep search parameters within ranges the underlying provider accepts.

Source

Thrown at clis/booking/search.js:17

import {
  ArgumentError,
  CommandExecutionError,
  EmptyResultError,
} from '@jackwener/opencli/errors';
import { cli, Strategy } from '@jackwener/opencli/registry';

const DATE_RE = /^\d{4}-\d{2}-\d{2}$/;

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

function normalizeNonNegativeInt(value, defaultValue, label, max) {
  const raw = value ?? defaultValue;
  const n = Number(raw);
  if (!Number.isInteger(n) || n < 0) {
    throw new ArgumentError(`${label} must be a non-negative integer`);
  }
  if (typeof max === 'number' && n > max) {
    throw new ArgumentError(`${label} must be <= ${max}`);
  }
  return n;
}

function normalizeDate(value, label) {
  const v = String(value || '').trim();

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Read the max value from the error message and pass a value at or below it (e.g. --adults 16).
  2. Clamp programmatically before calling: Math.min(value, MAX).
  3. If you need more results, lower per-call limit and paginate with offset instead of raising limit.

Example fix

// before
const limit = 500;
await bookingSearch({ limit }); // throws: limit must be <= 50
// after
const limit = Math.min(userLimit, 50);
await bookingSearch({ limit });
Defensive patterns

Strategy: validation

Validate before calling

const LIMITS = { adults: 16, rooms: 8, limit: 50 };
function clampInt(v, label) {
  const n = Math.max(1, Math.min(Number(v) || 1, LIMITS[label]));
  if (!Number.isInteger(n)) throw new Error(`${label} invalid`);
  return n;
}
const limit = clampInt(opts.limit ?? 10, 'limit');

Type guard

function isIntWithin(v, max) {
  return typeof v === 'number' && Number.isInteger(v) && v > 0 && v <= max;
}

Try / catch

try {
  await bookingSearch({ adults, rooms, limit });
} catch (e) {
  if (e instanceof ArgumentError && /must be <= \d+/.test(e.message)) {
    const max = Number(e.message.match(/<= (\d+)/)[1]);
    console.error(`${e.message} — retrying with the max`); // optionally retry clamped
  } else throw e;
}

Prevention

When it happens

Trigger: Calling search with e.g. adults: 20, rooms: 10, or limit: 1000 when the respective max caps are lower. The exact bound is stated in the message ('<label> must be <= <max>').

Common situations: Bulk/pagination code computing a huge limit; scripts defaulting adults to a large party size; copy-pasted config from another tool with different caps; misunderstanding that 'limit' is unbounded.

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/69a042acb14830d4. Report an issue: GitHub.