jackwener/OpenCLI · error · CommandExecutionError
twitter_likes_repeated_cursor
twitter_likes_repeated_cursor
Error message
twitter_likes_repeated_cursor: archive completion cannot be proven; resume state was retained
What it means
CommandExecutionError (code twitter_likes_repeated_cursor) thrown during pagination when the API returns the same bottom cursor twice in a row without the page being provably complete. Because completion cannot be proven, the library aborts and deliberately retains the resume file so a later run can retry from the last good cursor instead of marking the archive done.
Source
Thrown at clis/twitter/likes.js:344
allTweets.push(...tweets);
}
const pageComplete = !nextCursor;
writeResumeFile(resumeFile, {
cursor: pageComplete ? null : nextCursor,
count: useOutputFile ? outputCount : allTweets.length,
tweets: useOutputFile ? undefined : allTweets,
updatedAt: new Date().toISOString(),
complete: pageComplete,
source: 'likes',
username,
outputFile: useOutputFile ? outputFile : null,
});
if (pageComplete) {
exhausted = true;
break;
}
if (nextCursor === cursor) {
throw new CommandExecutionError('twitter_likes_repeated_cursor: archive completion cannot be proven; resume state was retained');
}
cursor = nextCursor;
}
const finalCount = useOutputFile ? outputCount : allTweets.length;
if (finalCount === 0) {
if (looksLikePrivateTwitterTimeline(lastRawResponse)) {
throw new EmptyResultError('twitter likes', `No likes returned for @${username} (Likes are private by default on X; only the account owner can view their own likes)`);
}
throw new EmptyResultError('twitter likes', `No likes found for @${username}`);
}
// Resume is only removed after the timeline is truly exhausted. Hitting
// --max-pages, partial API errors after some rows, or an interrupt must
// leave the resume file so the next run can continue.
if (exhausted)
removeResumeFile(resumeFile);
if (useOutputFile) {
return {
outputFile,View on GitHub (pinned to 49907e53dc)
Solutions
- Re-run the command with --resume: it continues from the retained cursor, often succeeding on retry.
- Wait a few minutes (transient Twitter flakiness) then resume.
- Re-authenticate if the session degraded mid-run, then resume.
- If it persists on every attempt, treat the archive as complete-at-last-stable-page or update query IDs and retry.
Example fix
// before $ cli twitter likes @user --all # aborted: repeated cursor // after $ cli twitter likes @user --all --resume # retry from retained cursor
Defensive patterns
Strategy: retry
Validate before calling
// track cursors yourself and abort early on repetition
let lastCursor = null;
if (nextCursor && nextCursor === lastCursor) {
await sleep(5000); // transient flakiness guard before resuming
} Type guard
null
Try / catch
try {
await cli.twitter.likes({ username, all: true, resume: true });
} catch (e) {
if (e.code === 'twitter_likes_repeated_cursor') {
await sleep(backoff); // resume state was retained; retry continues from cursor
return retryWithResume();
}
throw e;
} Prevention
- Always keep the resume file (the library retains it on purpose)
- Retry with backoff; repeated cursors are often transient
- Re-authenticate if long runs degrade mid-pagination
- Cap attempts (e.g. 3 retries) before accepting a partial archive
When it happens
Trigger: In the pagination loop at clis/twitter/likes.js:344, pageComplete is false and nextCursor === cursor (the same cursor value returned by two consecutive Likes pages).
Common situations: Twitter serving stale/cached timeline pages; flaky API responses mid-pagination; Twitter backend bug returning the cursor but no new entries; intermittent auth degradation during a long --all fetch.
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/574f4e7c20a719de.
Report an issue: GitHub.