jackwener/OpenCLI · error · ArgumentError

${label} must be a positive integer

Error message

${label} must be a positive integer

What it means

ArgumentError from normalizePositiveInteger, thrown when a validated option (limit, page, contentLimit, etc.) is not an integer or is <= 0. The library refuses to floor, clamp, or default invalid input silently — fail-fast validation per typed-fail-fast convention.

Source

Thrown at clis/1point3acres/utils.js:32

/**
 * Validate `limit` per typed-fail-fast convention (no silent clamp).
 * Throws ArgumentError on non-positive / non-integer / out-of-range input.
 */
export function normalizeLimit(value, defaultValue, maxValue, label = 'limit') {
    const limit = normalizePositiveInteger(value, defaultValue, label);
    if (limit > maxValue) {
        throw new ArgumentError(`${label} must be <= ${maxValue}`);
    }
    return limit;
}

/** Validate a positive integer argument without silently flooring/clamping. */
export function normalizePositiveInteger(value, defaultValue, label = 'value', { min = 1 } = {}) {
    const raw = value ?? defaultValue;
    const limit = Number(raw);
    if (!Number.isInteger(limit) || limit <= 0) {
        throw new ArgumentError(`${label} must be a positive integer`);
    }
    if (limit < min) {
        throw new ArgumentError(`${label} must be >= ${min}`);
    }
    return limit;
}

const UA = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0 Safari/537.36';

/** Fetch a GBK-encoded Discuz page and return decoded UTF-8 HTML. */
export async function fetchHtml(url, { headers = {}, cookie = '' } = {}) {
    let res;
    try {
        res = await fetch(url, {
            headers: {
                'User-Agent': UA,
                'Accept': 'text/html,application/xhtml+xml',
                'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Ensure the value is an integer > 0 before calling: Number.isInteger(v) && v > 0
  2. Parse CLI/URL input with parseInt/Number and check isNaN first
  3. Use page: 1 as the first page, not 0
  4. Check for NaN sources: an undefined variable used in arithmetic
  5. If a non-positive value is legitimate in your flow, guard it before calling rather than relying on the library default

Example fix

// before
thread({ tid: '123', page: 0 })  // ArgumentError: page must be a positive integer
// after
thread({ tid: '123', page: 1 })
Defensive patterns

Strategy: validation

Validate before calling

const toPositiveInt = (v) => {
  const n = Number(v);
  return Number.isInteger(n) && n > 0 ? n : null;
};
const page = toPositiveInt(rawPage); if (page === null) { /* fix input */ }

Type guard

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

Try / catch

try {
  await thread({ tid, page, limit });
} catch (e) {
  if (e instanceof ArgumentError && /must be a positive integer/.test(e.message)) {
    console.error(`${e.message} — check that ${e.message.split(' ')[0]} is an integer > 0, not a float, string, or NaN`);
  } else throw e;
}

Prevention

When it happens

Trigger: Passing page: 0, limit: -1, a float like 1.5, a non-numeric string like 'ten', NaN, or null combined with no default applying (note: null falls back to defaultValue, but undefined with no default → raw undefined → Number() = NaN → throws).

Common situations: Off-by-one loops starting at page 0; parsing CLI flags into floats ('3.0' passes Number.isInteger after Number()? yes — but '3.5' fails); string values from query params not parsed with parseInt; arithmetic producing NaN (e.g. undefined * 2).

Related errors


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