jackwener/OpenCLI · error · CommandExecutionError
Xiaoyuzhou playback progress returned unrequested eid ${eid}
Error message
Xiaoyuzhou playback progress returned unrequested eid ${eid} What it means
parseProgressRows builds a Map of the eids it explicitly requested from the history page and rejects any progress row whose eid was not requested. This guards against the server returning unrelated or wrong-scope progress records, which would silently corrupt the history/progress join.
Source
Thrown at clis/xiaoyuzhou/history.js:119
pubDate: optionalIsoTime(episode.pubDate, `pubDate in row ${rowNumber}`, { required: true }),
finished: episode.isFinished,
};
}
function parseProgressRows(response, episodes) {
if (!Array.isArray(response?.data)) {
throw new CommandExecutionError('Xiaoyuzhou playback progress returned an unexpected response shape');
}
const requested = new Map(episodes.map((episode) => [episode.eid, episode]));
const progressById = new Map();
for (const [index, row] of response.data.entries()) {
if (!isRecord(row)) {
throw new CommandExecutionError(`Xiaoyuzhou playback progress row ${index + 1} is malformed`);
}
const eid = requiredId(row.eid, `progress eid in row ${index + 1}`);
const episode = requested.get(eid);
if (!episode) {
throw new CommandExecutionError(`Xiaoyuzhou playback progress returned unrequested eid ${eid}`);
}
if (progressById.has(eid)) {
throw new CommandExecutionError(`Xiaoyuzhou playback progress returned duplicate eid ${eid}`);
}
const pid = requiredId(row.pid, `progress pid in row ${index + 1}`);
if (pid !== episode.pid) {
throw new CommandExecutionError(`Xiaoyuzhou playback progress pid did not match history eid ${eid}`);
}
const progressSec = optionalSeconds(row.progress, `progress in row ${index + 1}`);
if (progressSec !== null && episode.durationSec !== null && progressSec > episode.durationSec) {
throw new CommandExecutionError(`Xiaoyuzhou playback progress exceeded duration for eid ${eid}`);
}
progressById.set(eid, {
progressSec,
playedAt: optionalIsoTime(row.playedAt, `playedAt in row ${index + 1}`),
});
}
for (const episode of episodes) {View on GitHub (pinned to 49907e53dc)
Solutions
- Verify the eids sent in the request body match the returned rows — capture both sides of the call.
- Retry; a server-side filter regression may be transient or already fixed.
- Update the CLI/library in case id normalization (e.g. casing) changed and caused the mismatch.
- Check for server-side API changes where the progress endpoint stopped honoring the eids filter, and report it.
- As a workaround, use a lower --limit so fewer eids are in flight, reducing the chance of a mismatched row.
Example fix
// before (server ignores filter, returns everything)
{ "data": [ { "eid": "ffff...", "pid": "..." } ] } // ffff... was not requested
// after
{ "data": [ { "eid": "aabb...", "pid": "...", "progress": 120 } ] } // only requested eids Defensive patterns
Strategy: validation
Validate before calling
function requestedOnly(progressRows, eids) { const set = new Set(eids.map(e => String(e).toLowerCase())); return progressRows.every(r => set.has(String(r?.eid ?? '').toLowerCase())); } Type guard
function eidIsRequested(row, requestedEids) { return typeof row?.eid === 'string' && requestedEids.map(e => e.toLowerCase()).includes(row.eid.toLowerCase()); } Try / catch
try {
const rows = await runHistory();
} catch (e) {
if (/returned unrequested eid/.test(e.message)) {
// likely server ignoring the eids filter — retry, then report the API regression
} else throw e;
} Prevention
- Report/pin API versions where the progress endpoint's eids filter regressed
- Keep id casing consistent; the CLI lowercases ids, so ensure fixtures do too
- Capture both the request eids and response rows when debugging join mismatches
When it happens
Trigger: During `xiaoyuzhou history`, the progress endpoint returns a row whose eid is absent from the eids posted in the request body — e.g. the server ignores the eids filter, returns all account progress, or case-mismatched 24-hex ids fail the exact Map lookup.
Common situations: API regression where the eids filter is ignored; eid case differences (uppercase vs lowercase hex) after requiredId lowercased history ids; shared-account/sync quirks; mock fixtures returning canned full-list responses.
Related errors
- Xiaoyuzhou history returned an invalid loadMoreKey
- Xiaoyuzhou history returned an empty page with a continuatio
- Instagram following returned malformed users payload
- juejin recommend returned a malformed cursor
- juejin recommend returned a malformed has_more flag
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/042201d0567a3c01.
Report an issue: GitHub.