jackwener/OpenCLI · error · ArgumentError

--limit must be an integer between 1 and ${MAX_SEARCH_LIMIT}

Error message

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

What it means

parseSearchLimit converts the --limit option with Number(raw ?? 10) and requires a finite integer before range-checking. Non-numeric or non-integer inputs (e.g. 'abc', '2.5', '') throw this ArgumentError, echoing the original value via JSON.stringify. This is the type/coercion check; the 1..MAX range check is the separate follow-up error.

Source

Thrown at clis/douyin/search.js:56

 *
 * Prerequisite: the bound Chrome profile must be logged in to
 * https://www.douyin.com. The search results page renders an empty
 * skeleton for anonymous visitors, which we surface as AuthRequiredError.
 */
import { cli, Strategy } from '@jackwener/opencli/registry';
import { ArgumentError, AuthRequiredError, CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';

export const MAX_SEARCH_LIMIT = 30;
// Time budget for the SPA's initial DOM commit. Empirically the
// scroll-list `<li>` rows appear within 2-4s of navigation when logged
// in; 15s covers slow networks without blocking on a permanently-empty
// page (anonymous gate, network error).
export const RENDER_TIMEOUT_MS = 15000;

export function parseSearchLimit(raw) {
    const parsed = Number(raw ?? 10);
    if (!Number.isFinite(parsed) || !Number.isInteger(parsed)) {
        throw new ArgumentError(`--limit must be an integer between 1 and ${MAX_SEARCH_LIMIT}, got ${JSON.stringify(raw)}`);
    }
    if (parsed < 1 || parsed > MAX_SEARCH_LIMIT) {
        throw new ArgumentError(`--limit must be between 1 and ${MAX_SEARCH_LIMIT}, got ${parsed}`);
    }
    return parsed;
}

/**
 * Parse a Douyin display count like "1.9万", "3.1万", "4702", "1.2亿"
 * into a plain integer. Returns 0 for unparseable input rather than
 * throwing — the CLI promises numeric columns and missing data is
 * common enough on real result rows that a soft fallback is the right
 * choice.
 */
export function parseDouyinCount(text) {
    if (typeof text !== 'string') return 0;
    const m = text.replace(/\s/g, '').match(/^(\d+(?:\.\d+)?)([万亿])?$/);
    if (!m) {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass an integer value for --limit, e.g. --limit 20
  2. Remove thousands separators, units, or ranges from the value
  3. Coerce/validate in the calling script before invoking: Number.isInteger(Number(raw))

Example fix

// before
await douyin.search({ query: 'cats', limit: '1,000' });
// after
await douyin.search({ query: 'cats', limit: 50 });
Defensive patterns

Strategy: validation

Validate before calling

function parseLimit(raw) {
  const n = Number(raw ?? 10);
  if (!Number.isFinite(n) || !Number.isInteger(n)) throw new TypeError(`--limit must be an integer, got ${JSON.stringify(raw)}`);
  return n;
}

Type guard

function isValidLimit(v) {
  const n = Number(v);
  return Number.isFinite(n) && Number.isInteger(n);
}

Try / catch

try {
  await douyin.search({ query, limit: rawLimit });
} catch (e) {
  if (e instanceof ArgumentError && /must be an integer/.test(e.message)) {
    await douyin.search({ query, limit: 10 }); // fall back to default
  } else throw e;
}

Prevention

When it happens

Trigger: Calling the douyin search command with --limit set to a non-integer string, a non-numeric value, NaN-producing input like 'ten' or '1,000', or an empty string.

Common situations: CLI flags passed as free text by scripts; locale-formatted numbers ('1.000'); users assuming a range like '10-50' is accepted; YAML/JSON configs supplying strings instead of numbers.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


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