jackwener/OpenCLI · error · ArgumentError
--top-by-engagement cannot be combined with --output-file
Error message
--top-by-engagement cannot be combined with --output-file
What it means
The likes CLI rejects mutually exclusive options at argument-validation time: --top-by-engagement returns a ranked top-N subset, while --output-file streams the complete archive to disk; combining them is unsupported, so ArgumentError is thrown before any fetching begins.
Source
Thrown at clis/twitter/likes.js:212
{ name: 'username', type: 'string', positional: true, help: 'Twitter screen name (with or without @). Defaults to the logged-in user when omitted.' },
{ name: 'limit', type: 'int', default: 20, help: 'Maximum number of liked tweets to return (default 20). Ignored when --all is set.' },
{ name: 'all', type: 'bool', default: false, help: 'Fetch all liked-tweet pages until exhausted. Prefer --output-file for large archives.' },
{ name: 'resume-file', type: 'string', help: 'Resume file for long-running all-pages likes syncs.' },
{ name: 'output-file', type: 'string', help: 'Write all-page results to JSONL. Requires --all and --resume-file.' },
{ name: 'max-pages', type: 'int', help: `Optional pagination safety cap (default ${DEFAULT_MAX_PAGINATION_PAGES}; raised automatically with --all).` },
{ 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)View on GitHub (pinned to 49907e53dc)
Solutions
- Drop --top-by-engagement if you want the full archive streamed to the output file.
- Drop --output-file (and --resume-file) if you only want the top-N by engagement returned in memory.
Example fix
// before opencli twitter likes @jack --all --top-by-engagement 50 --output-file likes.ndjson // after (pick one intent) opencli twitter likes @jack --all --output-file likes.ndjson --resume-file likes.json
Defensive patterns
Strategy: validation
Validate before calling
const flags = ['--all', '--top-by-engagement', '50', '--output-file', 'likes.ndjson'];
if (flags.includes('--top-by-engagement') && flags.includes('--output-file')) {
throw new Error('Choose either top-N ranking or file output, not both');
} Prevention
- Decide the intent first: ranked top-N (in-memory) vs full archive (output-file).
- Build command lines from disjoint flag groups in scripts rather than concatenating examples.
- Validate flag combos in CI wrappers that assemble opencli commands.
When it happens
Trigger: Running e.g. `opencli twitter likes @jack --all --top-by-engagement 50 --output-file likes.ndjson --resume-file likes.json` — fetchAll with both an output file and a positive --top-by-engagement value.
Common situations: Copy-pasting flags from two different example commands; a script that appends --output-file for archiving onto an existing top-N command line.
Related errors
- --resume-file requires --all
- 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
- --output-file requires --all
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/c12d223baf364482.
Report an issue: GitHub.