{"record":{"id":"429f3b231e6a7cc7","repo":"jackwener/OpenCLI","slug":"resume-file-output-mismatch-expected-expected-o-429f3b","errorCode":null,"errorMessage":"Resume file output mismatch: expected ${expected.outputFile || 'in-memory mode'}, found ${outputFile || 'in-memory mode'}","messagePattern":"Resume file output mismatch: expected (.+?), found (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/twitter/likes.js","lineNumber":145,"sourceCode":"    catch (error) {\n        throw new CommandExecutionError(`Could not parse Twitter likes resume file ${filePath}: ${error instanceof Error ? error.message : String(error)}`);\n    }\n    const count = parsed?.count;\n    const cursor = parsed?.cursor == null ? null : String(parsed.cursor);\n    const outputFile = parsed?.outputFile ? path.resolve(String(parsed.outputFile)) : null;\n    if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)\n        || !Number.isInteger(count) || count < 0\n        || (parsed.cursor != null && typeof parsed.cursor !== 'string')\n        || (cursor !== null && !cursor.trim())) {\n        throw new CommandExecutionError(`Twitter likes resume file ${filePath} has an invalid shape`);\n    }\n    if (expected) {\n        if (parsed.source !== expected.source)\n            throw new ArgumentError(`Resume file source mismatch: expected ${expected.source}, found ${parsed.source || 'unknown'}`);\n        if (String(parsed.username || '').toLowerCase() !== String(expected.username).toLowerCase())\n            throw new ArgumentError(`Resume file username mismatch: expected @${expected.username}, found @${parsed.username || 'unknown'}`);\n        if (outputFile !== expected.outputFile)\n            throw new ArgumentError(`Resume file output mismatch: expected ${expected.outputFile || 'in-memory mode'}, found ${outputFile || 'in-memory mode'}`);\n        if (!expected.outputFile && !Array.isArray(parsed.tweets))\n            throw new CommandExecutionError(`Twitter likes resume file ${filePath} is missing in-memory tweets`);\n        if (!expected.outputFile && parsed.tweets.length !== count)\n            throw new CommandExecutionError(`Twitter likes resume file ${filePath} count does not match its in-memory tweets`);\n        if (parsed.complete)\n            throw new CommandExecutionError(`Twitter likes resume file ${filePath} is already marked complete`);\n    }\n    return {\n        cursor,\n        count,\n        tweets: Array.isArray(parsed.tweets) ? parsed.tweets : [],\n        username: parsed.username || null,\n        complete: Boolean(parsed.complete),\n        source: parsed.source || null,\n        outputFile,\n        updatedAt: parsed.updatedAt || null,\n    };\n}","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/likes.js#L127-L163","documentation":"readResumeFile checks that the resume file's resolved outputFile path equals the expected outputFile for the current run and throws this ArgumentError otherwise. In-memory mode (no output file) is compared with null/'in-memory mode', so resuming an output-file run as in-memory (or vice versa) is rejected to keep the resume semantics consistent.","triggerScenarios":"Running `twitter likes --resume <file>` where the file's resolved outputFile differs from expected.outputFile — e.g. the file was created with `--output likes.json` but the resuming run omits --output (in-memory), uses a different output path, or the file was moved so path.resolve yields a different absolute path.","commonSituations":"Running the resume command from a different working directory so the relative output path resolves elsewhere; forgetting the --output flag on the resume run; renaming/moving the output file between runs; sharing resume files across machines with different paths.","solutions":["Re-run the resume with the exact same --output path (absolute, or same cwd) used when the file was created","If in-memory mode is intended, use a resume file that was also created in in-memory mode","Prefer absolute --output paths so cwd changes don't alter the resolved path","Regenerate the resume file for the current output configuration"],"exampleFix":"// before\ntwitter likes --resume likes.json                    # in-memory, file was created with --output\n// after\ntwitter likes --resume likes.json --output /data/likes.json   # same path as original run","handlingStrategy":"validation","validationCode":"const parsed = JSON.parse(fs.readFileSync(resumePath, 'utf8'));\nconst resolvedOut = parsed.outputFile ? path.resolve(parsed.outputFile) : null;\nif (resolvedOut !== expectedOutputFile)\n  throw new Error(`output mismatch: pass --output ${resolvedOut ?? '(none/in-memory)'}`);","typeGuard":null,"tryCatchPattern":"try {\n  await runLikes({ resume: resumePath, output: outFile });\n} catch (e) {\n  if (/output mismatch/.test(e.message)) {\n    // re-run with the exact original --output path, or regenerate the resume\n  }\n  throw e;\n}","preventionTips":["Use absolute --output paths so cwd changes don't break resolution","Always pass the same --output flag on the resuming run","Don't move/rename the output file between runs","Record the original command line alongside the resume file"],"tags":["twitter","resume-file","argument-error","mismatch"],"backgroundTag":"resume-file-mismatch","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}