jackwener/OpenCLI · error · CommandExecutionError

Xiaoyuzhou history stopped at the --max-pages safety limit (

Error message

Xiaoyuzhou history stopped at the --max-pages safety limit (${maxPages}) before reaching the end

What it means

--max-pages is a safety cap on pagination. If the page limit is reached and the feed still has a next cursor, fetchHistory refuses to return a silently truncated result and throws, telling you the archive was not fully read.

Source

Thrown at clis/xiaoyuzhou/history.js:218

                        ? Number(((progress.progressSec / episode.durationSec) * 100).toFixed(1))
                        : null,
                    playedAt: progress.playedAt,
                    pubDate: episode.pubDate,
                    finished: episode.finished,
                    url: `https://www.xiaoyuzhoufm.com/episode/${episode.eid}`,
                });
            }
        }
        if (!fetchAll && rows.length >= limit) break;
        if (page.next === null) {
            exhausted = true;
            break;
        }
        if (page.next === loadMoreKey || seenCursors.has(page.next)) {
            throw new CommandExecutionError('Xiaoyuzhou history pagination repeated the same cursor');
        }
        if (pageNumber === maxPages) {
            throw new CommandExecutionError(
                `Xiaoyuzhou history stopped at the --max-pages safety limit (${maxPages}) before reaching the end`,
            );
        }
        seenCursors.add(page.next);
        loadMoreKey = page.next;
    }

    if (rows.length === 0) {
        throw new EmptyResultError('xiaoyuzhou history', 'The logged-in account has no playback history');
    }
    if (fetchAll && !exhausted) {
        throw new CommandExecutionError('Xiaoyuzhou history archive did not reach the end of pagination');
    }
    return rows;
}

cli({
    site: 'xiaoyuzhou',

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Raise the cap: pass a larger --max-pages (up to HARD_MAX_PAGES) for full-archive runs.
  2. Use --limit to fetch only the most recent N entries instead of the entire archive.
  3. If the cap fires alongside repeated-cursor errors, fix the cursor problem first — the cap may be masking a loop.
  4. Paginate in batches yourself: run with --limit, remember the last entry, and resume in a subsequent call if the API supports it.

Example fix

// before
await fetchHistory({ all: true }); // aborts at default max-pages
// after
await fetchHistory({ all: true, 'max-pages': 500 });
Defensive patterns

Strategy: validation

Validate before calling

if (fetchAll && expectedEntries > maxPages * pageSize) {
  throw new Error(`--max-pages too small; need ~${Math.ceil(expectedEntries / pageSize)} pages`);
}

Try / catch

try {
  return await fetchHistory({ all: true, 'max-pages': 500 });
} catch (e) {
  if (/max-pages safety limit/.test(e.message)) {
    console.error('Archive larger than page cap; raise --max-pages or use --limit');
  } else throw e;
}

Prevention

When it happens

Trigger: Fetching history with --all (or a large --limit) when the account has more pages than maxPages; using the default max-pages with a very large history; a stuck cursor making pagination never end until the cap triggers.

Common situations: Long-standing accounts with thousands of entries; DEFAULT_MAX_PAGES too small for the account; users unaware of the safety cap; the cap firing as the terminal symptom of a cursor loop (error 4926).

Related errors


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