{"record":{"id":"20c6e813cab7f0f4","repo":"jackwener/OpenCLI","slug":"output-file-requires-resume-file-so-partial-ar-20c6e8","errorCode":null,"errorMessage":"--output-file requires --resume-file so partial archives remain resumable","messagePattern":"--output-file requires --resume-file so partial archives remain resumable","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/twitter/likes.js","lineNumber":221,"sourceCode":"    func: async (page, kwargs) => {\n        const fetchAll = Boolean(kwargs.all);\n        const limit = fetchAll ? Number.POSITIVE_INFINITY : (kwargs.limit || 20);\n        const resumeFile = resolveOptionalFilePath(kwargs['resume-file'], '--resume-file');\n        const outputFile = resolveOptionalFilePath(kwargs['output-file'], '--output-file');\n        const useOutputFile = Boolean(fetchAll && outputFile);\n        const maxPages = resolveMaxPages(kwargs, fetchAll);\n        const topByEngagement = Number(kwargs['top-by-engagement'] || 0);\n        if (useOutputFile && topByEngagement > 0) {\n            throw new ArgumentError('--top-by-engagement cannot be combined with --output-file');\n        }\n        if (outputFile && !fetchAll) {\n            throw new ArgumentError('--output-file requires --all');\n        }\n        if (resumeFile && !fetchAll) {\n            throw new ArgumentError('--resume-file requires --all');\n        }\n        if (outputFile && !resumeFile) {\n            throw new ArgumentError('--output-file requires --resume-file so partial archives remain resumable');\n        }\n        const rawUsername = String(kwargs.username ?? '').trim();\n        let username = normalizeTwitterScreenName(rawUsername);\n        if (rawUsername && !username) {\n            throw new ArgumentError('twitter likes username must be a valid Twitter/X handle', 'Example: opencli twitter likes @jack --limit 20');\n        }\n        const cookies = await page.getCookies({ url: 'https://x.com' });\n        const ct0 = cookies.find((c) => c.name === 'ct0')?.value || null;\n        if (!ct0)\n            throw new AuthRequiredError('x.com', 'Not logged into x.com (no ct0 cookie)');\n        // If no username provided, detect the logged-in user.\n        // Bridge wraps primitive page.evaluate returns as { session, data:<value> };\n        // unwrap so the href string is usable downstream.\n        if (!username) {\n            // Force a navigation to the home surface so the AppTabBar sidebar\n            // is rendered; the framework pre-nav lands on bare x.com which\n            // does not always expose AppTabBar_Profile_Link.\n            await page.goto('https://x.com/home');","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/likes.js#L203-L239","documentation":"When --output-file is given, the run can be interrupted mid-archive; without a --resume-file the partial on-disk archive has no state to resume from and would be useless. The CLI therefore requires --resume-file alongside --output-file and throws ArgumentError otherwise.","triggerScenarios":"Running `opencli twitter likes @jack --all --output-file likes.ndjson` without --resume-file.","commonSituations":"User reads docs showing --output-file alone; older scripts written before the resumability requirement was added; simplifying a command line by dropping the 'extra' resume flag.","solutions":["Add --resume-file pointing to a JSON path (new or from a prior interrupted run) when using --output-file.","Remove --output-file if you don't need a disk archive and accept in-memory results."],"exampleFix":"// before\nopencli twitter likes @jack --all --output-file likes.ndjson\n// after\nopencli twitter likes @jack --all --output-file likes.ndjson --resume-file likes-resume.json","handlingStrategy":"validation","validationCode":"if (args.includes('--output-file') && !args.includes('--resume-file')) {\n  throw new Error('--output-file requires --resume-file');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass --output-file and --resume-file together as a pair.","Point both at the same working directory so partial archives remain resumable."],"tags":["cli","argument-validation","twitter","resume-file"],"backgroundTag":"missing-required-flag","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}