jackwener/OpenCLI · error · ArgumentError
maxScrolls must be a positive integer, got ${JSON.stringify(
Error message
maxScrolls must be a positive integer, got ${JSON.stringify(maxScrolls)} What it means
buildScrollUntilJs validates that maxScrolls is a safe integer >= 1 (default 15) and throws this ArgumentError otherwise. maxScrolls caps how many scroll iterations the generated IIFE performs to bound runtime, so a zero/negative/non-integer value is rejected before any browser JS is built.
Source
Thrown at clis/xiaohongshu/search.js:544
* ~5-7 notes per scroll, so the previous `times: 2` capped extraction at
* ~13 items regardless of `--limit` (see #1471). This helper drives scrolls
* dynamically:
*
* - count visible `section.note-item` rows (excluding related-search
* `.query-note-item` rows)
* - if count >= targetCount → break (got enough)
* - if two consecutive scrolls add no new rows → break (DOM plateaued,
* no more lazy-load available)
* - hard cap at `maxScrolls` iterations (default 15) to bound runtime
*
* Exported so the rednote adapter (same DOM shape) can reuse it.
*/
export function buildScrollUntilJs(targetCount, maxScrolls = 15) {
if (!Number.isSafeInteger(targetCount) || targetCount < 1) {
throw new ArgumentError(`targetCount must be a positive integer, got ${JSON.stringify(targetCount)}`);
}
if (!Number.isSafeInteger(maxScrolls) || maxScrolls < 1) {
throw new ArgumentError(`maxScrolls must be a positive integer, got ${JSON.stringify(maxScrolls)}`);
}
return `
(async () => {
const isVisibleNote = (el) => {
if (el.classList.contains('query-note-item')) return false;
const rect = el.getBoundingClientRect();
if (rect.width <= 0 || rect.height <= 0) return false;
const style = getComputedStyle(el);
return style.display !== 'none' && style.visibility !== 'hidden';
};
// Note containers: legacy \`section.note-item\` first, fallback to
// any \`<section>\` that wraps a search-result/explore note link
// (#1506 reports the class being dropped on some xhs renders).
const collectNoteCards = () => {
const classMatches = document.querySelectorAll('section.note-item');
if (classMatches.length > 0) return classMatches;
const sections = new Set();
for (const a of document.querySelectorAll('a[href*="/search_result/"], a[href*="/explore/"]')) {View on GitHub (pinned to 49907e53dc)
Solutions
- Omit the second argument to use the safe default of 15.
- Pass a positive safe integer, e.g. buildScrollUntilJs(50, 30) for more scrolls.
- Validate/parse config values before passing: Number.isSafeInteger(cfg.maxScrolls).
- Clamp with Math.max(1, Math.trunc(n)) when deriving the cap dynamically.
Example fix
// before buildScrollUntilJs(limit, config.scrollMax); // after const maxScrolls = Number.isSafeInteger(config.scrollMax) && config.scrollMax >= 1 ? config.scrollMax : 15; buildScrollUntilJs(limit, maxScrolls);
Defensive patterns
Strategy: validation
Validate before calling
function assertMaxScrolls(v) {
if (!Number.isSafeInteger(v) || v < 1) {
throw new TypeError(`maxScrolls must be a positive safe integer, got ${JSON.stringify(v)}`);
}
}
assertMaxScrolls(maxScrolls ?? 15); Type guard
const isValidMaxScrolls = (v) => Number.isSafeInteger(v) && v >= 1;
Prevention
- Rely on the default (15) unless you have a measured reason to change it.
- Validate YAML/JSON config numbers — they often arrive as strings or null.
- Never pass 0 expecting 'unlimited'; maxScrolls must be >= 1.
- Clamp derived values with Math.max(1, Math.trunc(v)).
- Type-check callers (JSDoc/TS) so non-number args fail at review time.
When it happens
Trigger: Calling buildScrollUntilJs(targetCount, maxScrolls) with 0, a negative value, undefined, NaN, Infinity, or a float as the second argument.
Common situations: Overriding the default with a config value that is unset (undefined) or a string from YAML/JSON config; passing 0 intending 'no extra scrolls'; a computation producing NaN due to earlier string math.
Related errors
- targetCount must be a positive integer, got ${JSON.stringify
- maxRounds must be a positive integer, got ${JSON.stringify(m
- budgetMs must be a positive number, got ${JSON.stringify(bud
- step must be a non-negative number, got ${JSON.stringify(ste
- Omni Reference accepts exactly one local image
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/65077822dfb5faf6.
Report an issue: GitHub.