jackwener/OpenCLI · error · CommandExecutionError
Xiaoyuzhou history repeated eid ${episode.eid}; the paginati
Error message
Xiaoyuzhou history repeated eid ${episode.eid}; the pagination snapshot may have changed and event-vs-overlap semantics are ambiguous What it means
fetchHistory paginates the history feed and tracks every eid it has seen. If the same eid appears on a later page, the pagination snapshot changed between requests (new items inserted shifted entries across pages), making it ambiguous whether repeats are distinct play events or overlap artifacts. The library throws rather than guessing event-vs-overlap semantics.
Source
Thrown at clis/xiaoyuzhou/history.js:172
let credentials = loadXiaoyuzhouCredentials();
const seenEpisodeIds = new Set();
const seenCursors = new Set();
const rows = [];
let loadMoreKey = null;
let exhausted = false;
for (let pageNumber = 1; pageNumber <= maxPages; pageNumber += 1) {
const historyResponse = await requestXiaoyuzhouJson(HISTORY_ENDPOINT, {
method: 'POST',
body: loadMoreKey === null ? {} : { loadMoreKey },
credentials,
});
credentials = historyResponse.credentials;
const page = parseHistoryPage(historyResponse);
const episodes = page.entries.map((entry, index) => parseHistoryEpisode(entry, index + 1));
for (const episode of episodes) {
if (seenEpisodeIds.has(episode.eid)) {
throw new CommandExecutionError(
`Xiaoyuzhou history repeated eid ${episode.eid}; the pagination snapshot may have changed and event-vs-overlap semantics are ambiguous`,
);
}
seenEpisodeIds.add(episode.eid);
}
const remaining = fetchAll ? episodes.length : limit - rows.length;
const selected = episodes.slice(0, remaining);
if (selected.length > 0) {
const progressResponse = await requestXiaoyuzhouJson(PROGRESS_ENDPOINT, {
method: 'POST',
body: { eids: selected.map((episode) => episode.eid) },
credentials,
});
credentials = progressResponse.credentials;
const progressById = parseProgressRows(progressResponse, selected);
for (const episode of selected) {
const progress = progressById.get(episode.eid);View on GitHub (pinned to 49907e53dc)
Solutions
- Retry the full fetch (ideally with --all) during a quiet period so the server snapshot is stable between pages.
- Confirm the API supports a snapshot/anchor parameter and pass it so pages come from one consistent snapshot.
- If you only need recent history, use --limit instead of paginating the whole archive, reducing the window for changes.
- Reduce time between page requests (avoid long delays/rate-limit backoff that widen the change window).
Example fix
// before
await fetchHistory({ all: true }); // long unattended run, may abort
// after
let rows;
for (let attempt = 0; attempt < 3; attempt++) {
try { rows = await fetchHistory({ all: true }); break; }
catch (e) {
if (!/repeated eid/.test(e.message) || attempt === 2) throw e;
await new Promise(r => setTimeout(r, 2000));
}
} Defensive patterns
Strategy: retry
Try / catch
for (let i = 0; i < 3; i++) {
try { return await fetchHistory({ all: true }); }
catch (e) {
if (/repeated eid/.test(e.message) && i < 2) { await new Promise(r => setTimeout(r, 2000)); continue; }
throw e;
}
} Prevention
- Run full-archive fetches when the account is idle.
- Prefer --limit for recent history to shorten the pagination window.
- Minimize delay between page requests.
- Use a snapshot/anchor parameter if the API supports one.
When it happens
Trigger: New history entries are added server-side while paginating, shifting later entries onto already-fetched positions; cursor-based pagination without snapshot isolation; repeated loadMore cursors returning overlapping data.
Common situations: An active account playing episodes during a long --all fetch; APIs without snapshot isolation; clock skew between client and server; very old recorded fixtures replayed with shifting data.
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/e961f1091def3bc8.
Report an issue: GitHub.