jackwener/OpenCLI · warning · ArgumentError

--limit must be an integer between ${HOT_MIN_LIMIT} and ${HO

Error message

--limit must be an integer between ${HOT_MIN_LIMIT} and ${HOT_MAX_LIMIT}, got ${JSON.stringify(raw)}

What it means

parseHotLimit validates the `--limit` option of the toutiao hot command. This throw fires when the value is not a finite integer (e.g. 'abc', '3.5', '1e3', NaN). The library requires an integer count of hot items so it can page the upstream API deterministically.

Source

Thrown at clis/toutiao/utils.js:50

        throw new ArgumentError(`--limit must be between ${RECOMMEND_MIN_LIMIT} and ${RECOMMEND_MAX_LIMIT}, got ${parsed}`);
    }
    return parsed;
}

export function parseRecommendCategory(raw, fallback = '__all__') {
    if (raw === undefined || raw === null || raw === '') return fallback;
    const value = String(raw).trim();
    if (!RECOMMEND_CATEGORIES.includes(value)) {
        throw new ArgumentError(`--category must be one of ${RECOMMEND_CATEGORIES.join(', ')}, got ${JSON.stringify(raw)}`);
    }
    return value;
}

export function parseHotLimit(raw, fallback = 30) {
    if (raw === undefined || raw === null || raw === '') return fallback;
    const parsed = Number(raw);
    if (!Number.isFinite(parsed) || !Number.isInteger(parsed)) {
        throw new ArgumentError(`--limit must be an integer between ${HOT_MIN_LIMIT} and ${HOT_MAX_LIMIT}, got ${JSON.stringify(raw)}`);
    }
    if (parsed < HOT_MIN_LIMIT || parsed > HOT_MAX_LIMIT) {
        throw new ArgumentError(`--limit must be between ${HOT_MIN_LIMIT} and ${HOT_MAX_LIMIT}, got ${parsed}`);
    }
    return parsed;
}

const NON_TITLE_LINES = new Set([
    '展现', '阅读', '点赞', '评论',
    '查看数据', '查看评论', '修改', '更多', '首发',
    '已发布', '定时发布', '定时发布中', '由文章生成', '审核中',
]);

const STATS_RE = /展现\s*([\d,]+)\s*阅读\s*([\d,]+)\s*点赞\s*([\d,]+)\s*评论\s*([\d,]*)/;

/**
 * Extract creator-backend article rows from the rendered text dump.
 *

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass a plain integer between 1 and 50, e.g. --limit 30.
  2. Parse/sanitize first: Number.parseInt(String(raw), 10) and check Number.isInteger before invoking.
  3. Omit --limit to use the default of 30.
  4. Fix the calling script so the shell variable is quoted and guaranteed numeric.

Example fix

// before
toutiao hot --limit "$LIMIT_ITEMS"   # LIMIT_ITEMS='30 items'
// after
toutiao hot --limit 30
Defensive patterns

Strategy: validation

Validate before calling

const n = Number.parseInt(String(raw), 10);
if (!Number.isInteger(n) || String(n) !== String(raw).trim()) throw new TypeError(`--limit must be an integer, got ${JSON.stringify(raw)}`);

Type guard

const isIntString = (v) => /^-?\d+$/.test(String(v).trim());

Try / catch

try {
  parseHotLimit(raw);
} catch (e) {
  if (e instanceof ArgumentError) { console.error(e.message); process.exitCode = 2; }
  else throw e;
}

Prevention

When it happens

Trigger: Calling toutiao hot with --limit set to a non-integer or non-numeric string: --limit abc, --limit 3.5, --limit 10x, --limit NaN, or a shell variable that expanded to garbage.

Common situations: Passing float averages from prior computations; unquoted/unset shell variables interpolating empty or text; parsing JSON where the field was a string like "30" with units ('30 items'); typos like '--limit 3o'.

Related errors


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