jackwener/OpenCLI · warning · ArgumentError

--limit must be a positive integer, got ${parsed}

Error message

--limit must be a positive integer, got ${parsed}

What it means

parseLimit also rejects integers below 1. If the coerced value is a valid integer but parsed < 1 (e.g. 0 or -5), it throws ArgumentError with the numeric value. Note the error text says 'positive integer' but 0/negatives also fail here.

Source

Thrown at clis/xiaohongshu/feed.js:25

 * could not be passed to `note`/`comments`/`download` (which require a signed
 * URL). The hydrated store, by contrast, holds `entry.xsecToken` for every
 * first-screen note, so a func-mode read yields signed, drill-down-ready URLs.
 *
 * Mirrors rednote/feed.js: the hydrated store is camelCase on both sites
 * (`noteCard.displayTitle`, `interactInfo.likedCount`). This is the SSR store
 * shape, not the snake_case `/homefeed` API response the old tap intercepted.
 */
import { cli, Strategy } from '@jackwener/opencli/registry';
import { ArgumentError, CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';
import { unwrapEvaluateResult } from './shared.js';

function parseLimit(raw) {
    const parsed = Number(raw ?? 20);
    if (!Number.isFinite(parsed) || !Number.isInteger(parsed)) {
        throw new ArgumentError(`--limit must be a positive integer, got ${JSON.stringify(raw)}`);
    }
    if (parsed < 1) {
        throw new ArgumentError(`--limit must be a positive integer, got ${parsed}`);
    }
    return parsed;
}

const FEEDS_READ_JS = `
  (() => {
    let pinia = null;
    const probe = (el) => el?.__vue_app__?.config?.globalProperties?.$pinia ?? null;
    pinia = probe(document.querySelector('#app'));
    if (!pinia) {
      // Some builds mount under a different root id; fall back to a full scan
      // only when the standard mount node misses.
      for (const el of document.querySelectorAll('*')) {
        pinia = probe(el);
        if (pinia) break;
      }
    }
    if (!pinia || !pinia._s) return { error: 'no_pinia' };

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass an integer >= 1: --limit 1 for a single item
  2. Fix the upstream calculation producing 0/negative page sizes
  3. Omit --limit to use the default of 20

Example fix

// before
xhs feed --limit 0
// after
xhs feed --limit 20
Defensive patterns

Strategy: validation

Validate before calling

const n = Number(raw);
if (raw != null && Number.isInteger(n) && n < 1) throw new Error(`--limit must be >= 1, got ${n}`);

Type guard

function isPositiveLimit(raw) { if (raw == null) return true; const n = Number(raw); return Number.isInteger(n) && n >= 1; }

Try / catch

try {
  await cli.feed({ limit });
} catch (err) {
  if (err instanceof ArgumentError && err.message.startsWith('--limit')) {
    console.error('limit must be >= 1; defaulting to 20');
  } else throw err;
}

Prevention

When it happens

Trigger: Calling the feed command with --limit 0, --limit -1, or any negative integer.

Common situations: Users trying 'unlimited' with --limit 0, scripts computing a page size that underflows to 0 or negative, off-by-one bugs in wrapper scripts.

Related errors


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