jackwener/OpenCLI · error · ArgumentError

--limit must be between 1 and ${MAX_SEARCH_LIMIT}, got ${par

Error message

--limit must be between 1 and ${MAX_SEARCH_LIMIT}, got ${parsed}

What it means

The second check in parseSearchLimit: once the value is confirmed a finite integer, it must be within [1, MAX_SEARCH_LIMIT]. Values below 1 or above the maximum throw this ArgumentError with the parsed number. It exists because Douyin's search result page only supports a bounded display count.

Source

Thrown at clis/douyin/search.js:59

 * 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) {
        const plain = Number(text.replace(/[,\s]/g, ''));
        return Number.isFinite(plain) ? Math.round(plain) : 0;
    }

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Clamp the value into range before calling: Math.min(Math.max(1, n), MAX_SEARCH_LIMIT)
  2. Page through results with multiple calls using limit <= MAX_SEARCH_LIMIT instead of one large request
  3. Check the library's MAX_SEARCH_LIMIT export for the current bound

Example fix

// before
await douyin.search({ query: 'cats', limit: 500 });
// after
const limit = Math.min(Math.max(1, requested), 50);
await douyin.search({ query: 'cats', limit });
Defensive patterns

Strategy: validation

Validate before calling

const MAX_SEARCH_LIMIT = 50; // import from the library
function clampLimit(raw) {
  const n = Math.trunc(Number(raw ?? 10));
  return Math.min(Math.max(1, n), MAX_SEARCH_LIMIT);
}

Type guard

function limitInRange(v, max) {
  return Number.isInteger(v) && v >= 1 && v <= max;
}

Try / catch

try {
  await douyin.search({ query, limit: rawLimit });
} catch (e) {
  if (e instanceof ArgumentError && /must be between 1 and/.test(e.message)) {
    await douyin.search({ query, limit: clampLimit(rawLimit) });
  } else throw e;
}

Prevention

When it happens

Trigger: Passing --limit 0, a negative number, or an integer greater than MAX_SEARCH_LIMIT (e.g. --limit 500 if the max is 50).

Common situations: Users wanting 'all results' guessing an arbitrarily large limit; loop scripts computing limit = total - offset yielding 0 on the last page; off-by-one when a results set is empty.

Related errors


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