jackwener/OpenCLI · error · ArgumentError
--resume-file requires --all
Error message
--resume-file requires --all
What it means
The twitter bookmarks CLI requires --resume-file to be paired with --all because resume state (cursor, counts) is only meaningful for a full-archive run. Argument validation at clis/twitter/bookmarks.js:199 throws ArgumentError when a resume file is given but --all is absent. This prevents partial (--limit style) fetches from silently ignoring or corrupting resume state.
Source
Thrown at clis/twitter/bookmarks.js:199
{ name: 'top-by-engagement', type: 'int', default: 0, help: 'When set to N>0, re-rank the bookmarks by weighted engagement (likes×1 + retweets×3 + replies×2 + bookmarks×5 + log10(views+1)×0.5) and return the top N. Default 0 keeps the API\'s native (saved-time) ordering. Incompatible with --output-file.' },
],
columns: ['id', 'author', 'text', 'likes', 'retweets', 'bookmarks', 'created_at', 'url', 'has_media', 'media_urls', 'media_posters'],
func: async (page, kwargs) => {
const fetchAll = Boolean(kwargs.all);
const limit = fetchAll ? Number.POSITIVE_INFINITY : (kwargs.limit || 20);
const resumeFile = resolveOptionalFilePath(kwargs['resume-file'], '--resume-file');
const outputFile = resolveOptionalFilePath(kwargs['output-file'], '--output-file');
const useOutputFile = Boolean(fetchAll && outputFile);
const maxPages = resolveMaxPages(kwargs, fetchAll);
const topByEngagement = Number(kwargs['top-by-engagement'] || 0);
if (useOutputFile && topByEngagement > 0) {
throw new ArgumentError('--top-by-engagement cannot be combined with --output-file');
}
if (outputFile && !fetchAll) {
throw new ArgumentError('--output-file requires --all');
}
if (resumeFile && !fetchAll) {
throw new ArgumentError('--resume-file requires --all');
}
if (outputFile && !resumeFile) {
throw new ArgumentError('--output-file requires --resume-file so partial archives remain resumable');
}
const cookies = await page.getCookies({ url: 'https://x.com' });
const ct0 = cookies.find((c) => c.name === 'ct0')?.value || null;
if (!ct0)
throw new AuthRequiredError('x.com', 'Not logged into x.com (no ct0 cookie)');
const queryId = await resolveTwitterQueryId(page, 'Bookmarks', BOOKMARKS_QUERY_ID);
const headers = JSON.stringify({
'Authorization': `Bearer ${decodeURIComponent(TWITTER_BEARER_TOKEN)}`,
'X-Csrf-Token': ct0,
'X-Twitter-Auth-Type': 'OAuth2Session',
'X-Twitter-Active-User': 'yes',
});
const resumed = fetchAll ? readResumeFile(resumeFile, {
source: 'bookmarks',
outputFile: useOutputFile ? outputFile : null,View on GitHub (pinned to 49907e53dc)
Solutions
- Add --all to the command so the fetch runs in full-archive mode where resume files apply.
- Drop --resume-file if you only want a partial fetch; resume state only applies to full archives.
- Update wrapper scripts/aliases to always pass --all and --resume-file together.
Example fix
// before twitter bookmarks --resume-file ./resume.json // after twitter bookmarks --all --resume-file ./resume.json
Defensive patterns
Strategy: validation
Validate before calling
const args = process.argv.slice(2);
const has = (f) => args.includes(f);
if (has('--resume-file') && !has('--all')) {
throw new Error('--resume-file requires --all');
} Type guard
function isFullArchiveResume(opts) {
return typeof opts.resumeFile === 'string' && opts.resumeFile.length > 0 && opts.fetchAll === true;
} Try / catch
try {
await runBookmarks(argv);
} catch (e) {
if (e instanceof ArgumentError && e.message.includes('--resume-file requires --all')) {
console.error('Usage: twitter bookmarks --all --resume-file <path>');
process.exitCode = 2;
} else throw e;
} Prevention
- Always pass --all and --resume-file as a pair; wrap them in one script or alias.
- Validate flag combinations in your wrapper before invoking the CLI.
- Read the CLI usage/help output before composing flag sets.
When it happens
Trigger: Running `twitter bookmarks --resume-file <path>` without `--all`. The check is `if (resumeFile && !fetchAll)` in the command's argument validation block, executed before any network calls.
Common situations: Users continuing a previously interrupted full archive forget to re-add --all; shell aliases or scripts that hardcode --resume-file for every invocation; documentation examples copied incompletely.
Related errors
- twitter download requires either <username> or --tweet-url
- Use either <username> or --tweet-url, not both
- twitter download username must be a valid Twitter/X handle
- --top-by-engagement cannot be combined with --output-file
- --output-file requires --all
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/b5b6ed3165246092.
Report an issue: GitHub.