jackwener/OpenCLI · error · ArgumentError

--resume-file requires --all

Error message

--resume-file requires --all

What it means

Same family as the previous check: --resume-file (the resumable state store) is only wired up for full-archive (--all) runs. Without --all the resume machinery is not engaged, so ArgumentError is thrown during argument validation.

Source

Thrown at clis/twitter/likes.js:218

        { name: 'top-by-engagement', type: 'int', default: 0, help: 'When set to N>0, re-rank the liked tweets 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 (recency) ordering. Incompatible with --output-file.' },
    ],
    columns: ['id', 'author', 'name', 'text', 'likes', 'retweets', '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 rawUsername = String(kwargs.username ?? '').trim();
        let username = normalizeTwitterScreenName(rawUsername);
        if (rawUsername && !username) {
            throw new ArgumentError('twitter likes username must be a valid Twitter/X handle', 'Example: opencli twitter likes @jack --limit 20');
        }
        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)');
        // If no username provided, detect the logged-in user.
        // Bridge wraps primitive page.evaluate returns as { session, data:<value> };
        // unwrap so the href string is usable downstream.
        if (!username) {
            // Force a navigation to the home surface so the AppTabBar sidebar

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Add --all to the command so resume state is actually used.
  2. Remove --resume-file if you are doing a small paginated fetch that doesn't need resuming.

Example fix

// before
opencli twitter likes @jack --limit 500 --resume-file likes.json
// after
opencli twitter likes @jack --all --resume-file likes.json --output-file likes.ndjson
Defensive patterns

Strategy: validation

Validate before calling

if (args.includes('--resume-file') && !args.includes('--all')) {
  throw new Error('--resume-file requires --all');
}

Prevention

When it happens

Trigger: Running `opencli twitter likes @jack --resume-file likes.json` (or with --limit) without --all.

Common situations: User wants checkpointing for a long limited pull and adds --resume-file, not realizing it applies only to --all; automation templates carrying --resume-file into short test invocations.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/0850a09e0606a0f0. Report an issue: GitHub.