jackwener/OpenCLI · error · CommandExecutionError
Xiaoyuzhou history archive did not reach the end of paginati
Error message
Xiaoyuzhou history archive did not reach the end of pagination
What it means
With --all set, fetchHistory promises the complete archive. If pagination ended without observing page.next === null — i.e. exhaustion was never confirmed — it throws rather than returning data that may be silently incomplete.
Source
Thrown at clis/xiaoyuzhou/history.js:230
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',
name: 'history',
access: 'read',
description: 'List playback history for the logged-in Xiaoyuzhou account',
domain: 'api.xiaoyuzhoufm.com',
strategy: Strategy.LOCAL,
browser: false,
args: [
{ name: 'limit', type: 'int', default: DEFAULT_LIMIT, help: `Maximum rows to return (default ${DEFAULT_LIMIT}, max ${MAX_LIMIT}). Ignored with --all.` },
{ name: 'all', type: 'bool', default: false, help: 'Fetch every history page until the API cursor is exhausted.' },
{ name: 'max-pages', type: 'int', default: DEFAULT_MAX_PAGES, help: `Pagination safety limit (default ${DEFAULT_MAX_PAGES}, max ${HARD_MAX_PAGES}).` },
],
columns: ['rank', 'eid', 'pid', 'title', 'podcast', 'durationSec', 'progressSec', 'progressPct', 'playedAt', 'pubDate', 'finished', 'url'],View on GitHub (pinned to 49907e53dc)
Solutions
- Inspect the final page's raw response to see how end-of-pagination is signaled and update the exhaustion check (e.g. treat '' or a sentinel as null).
- Retry the full --all fetch; transient issues may resolve.
- Fall back to --limit/--max-pages with incremental resumption if true exhaustion cannot be detected with the current API.
- Verify no middleware/proxy is truncating the final response that carries the null next cursor.
Example fix
// before
if (page.next === null) { exhausted = true; break; }
// after (API signals end with empty string)
if (page.next === null || page.next === '' || page.next === undefined) { exhausted = true; break; } Defensive patterns
Strategy: try-catch
Try / catch
try {
return await fetchHistory({ all: true });
} catch (e) {
if (e instanceof CommandExecutionError && /did not reach the end of pagination/.test(e.message)) {
console.error('Exhaustion signal unrecognized; check API end-of-pages contract');
} else throw e;
} Prevention
- Update exhaustion detection when the API changes its end-of-pagination signal.
- Retry --all runs once before surfacing the failure.
- Fall back to limited fetches with incremental resumption if exhaustion cannot be confirmed.
When it happens
Trigger: A --all run stops while a next cursor still exists — e.g. the loop ends early after a swallowed transient error, an API returns an unexpected cursor shape so exhaustion is never detected, or cursor handling bugs make page.next never null.
Common situations: API changes the end-of-pagination signal (next becomes '' or a sentinel instead of null); --all runs interrupted by transient errors that a wrapper turns into a normal return; middleware truncating the final empty-next response.
Related errors
- Bilibili view API did not return pages[] for --page selectio
- 分P 序号超出范围:p=${pageNum}(该视频共 ${total} 集)
- Jike search API returned a malformed pagination cursor
- Jike search pagination returned a repeated cursor
- Midjourney history endpoint returned a malformed payload
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/03aadb38fc138c63.
Report an issue: GitHub.