jackwener/OpenCLI · error · CommandExecutionError
twitter_bookmarks_archive_incomplete
twitter_bookmarks_archive_incomplete
Error message
twitter_bookmarks_archive_incomplete: stopped after ${pages} page(s); completion cannot be proven What it means
Thrown when a full-bookmark archive run (--all) stops paginating without reaching the natural end of the timeline, so the tool cannot prove every bookmark was captured. The library refuses to report an 'archive' result it cannot guarantee complete, and instead surfaces the resume cursor file so the run can be continued.
Source
Thrown at clis/twitter/bookmarks.js:305
throw new EmptyResultError('twitter bookmarks', 'No bookmarks found for the logged-in account');
}
// 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,
count: outputCount,
source: 'bookmarks',
complete: exhausted,
pages,
...(exhausted ? {} : { cursor, resumeFile: resumeFile || null }),
};
}
if (fetchAll && !exhausted) {
throw new CommandExecutionError(
`twitter_bookmarks_archive_incomplete: stopped after ${pages} page(s); completion cannot be proven`,
resumeFile ? `Resume with --resume-file ${resumeFile}` : 'Rerun with --resume-file to preserve continuation state.',
);
}
const trimmed = fetchAll ? allTweets : allTweets.slice(0, limit);
return applyTopByEngagement(trimmed, topByEngagement);
},
});
export const __test__ = {
parseBookmarks,
extractBookmarkTweet,
readResumeFile,
};
View on GitHub (pinned to 49907e53dc)
Solutions
- Rerun with --resume-file <path> so pagination state (cursor) is persisted and can continue where the run stopped
- Check for rate-limit headers/errors from X and wait before retrying the resume run
- Verify the account's bookmark count against the pages fetched to see if truncation is systemic
- Reduce per-request pressure (slower page delay, smaller page size) and resume again
Example fix
// before npx opencli twitter bookmarks --all // after npx opencli twitter bookmarks --all --resume-file ./bookmarks-resume.json # on stop: npx opencli twitter bookmarks --all --resume-file ./bookmarks-resume.json --resume
Defensive patterns
Strategy: try-catch
Validate before calling
const args = ['twitter','bookmarks','--all'];
if (!args.includes('--resume-file')) {
const resume = `./bookmarks-resume-${Date.now()}.json`;
args.push('--resume-file', resume); // preserve cursor so stops are resumable
} Type guard
function isCompleteArchive(result) {
return result != null && result.complete === true && typeof result.pages === 'number';
} Try / catch
try {
const archive = await runTwitterBookmarks({ all: true, resumeFile });
if (!archive.complete) throw new Error('incomplete');
} catch (err) {
if (String(err.message).startsWith('twitter_bookmarks_archive_incomplete')) {
// rerun with --resume-file <resumeFile> --resume
} else throw err;
} Prevention
- Always pass --resume-file on --all runs so any stop is resumable
- Run archives with generous rate-limit headroom and page delays
- After completion, verify result.complete === true before trusting the dataset
- Schedule large archives during low-traffic windows to reduce mid-run rate limits
When it happens
Trigger: fetchAll is true, the X bookmarks endpoint stops returning a cursor / exhausts pages before exhausted=true (rate limiting, API truncation, page cap), and a CommandExecutionError is raised with the page count.
Common situations: Large bookmark collections hitting API page limits or rate limits mid-run; X GraphQL changes that end pagination early; interrupted sessions where the cursor was lost before the resume file was set.
Related errors
- twitter_bookmarks_repeated_cursor
- twitter_collection_invalid_timestamp
- twitter_collection_limit_reached
- twitter_collection_repeated_cursor
- twitter_collection_page_guard_hit
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/3747130c96793536.
Report an issue: GitHub.