jackwener/OpenCLI · error · ArgumentError
Resume file output mismatch: expected ${expected.outputFile
Error message
Resume file output mismatch: expected ${expected.outputFile || 'in-memory mode'}, found ${outputFile || 'in-memory mode'} What it means
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.
Source
Thrown at clis/twitter/likes.js:145
catch (error) {
throw new CommandExecutionError(`Could not parse Twitter likes resume file ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
}
const count = parsed?.count;
const cursor = parsed?.cursor == null ? null : String(parsed.cursor);
const outputFile = parsed?.outputFile ? path.resolve(String(parsed.outputFile)) : null;
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)
|| !Number.isInteger(count) || count < 0
|| (parsed.cursor != null && typeof parsed.cursor !== 'string')
|| (cursor !== null && !cursor.trim())) {
throw new CommandExecutionError(`Twitter likes resume file ${filePath} has an invalid shape`);
}
if (expected) {
if (parsed.source !== expected.source)
throw new ArgumentError(`Resume file source mismatch: expected ${expected.source}, found ${parsed.source || 'unknown'}`);
if (String(parsed.username || '').toLowerCase() !== String(expected.username).toLowerCase())
throw new ArgumentError(`Resume file username mismatch: expected @${expected.username}, found @${parsed.username || 'unknown'}`);
if (outputFile !== expected.outputFile)
throw new ArgumentError(`Resume file output mismatch: expected ${expected.outputFile || 'in-memory mode'}, found ${outputFile || 'in-memory mode'}`);
if (!expected.outputFile && !Array.isArray(parsed.tweets))
throw new CommandExecutionError(`Twitter likes resume file ${filePath} is missing in-memory tweets`);
if (!expected.outputFile && parsed.tweets.length !== count)
throw new CommandExecutionError(`Twitter likes resume file ${filePath} count does not match its in-memory tweets`);
if (parsed.complete)
throw new CommandExecutionError(`Twitter likes resume file ${filePath} is already marked complete`);
}
return {
cursor,
count,
tweets: Array.isArray(parsed.tweets) ? parsed.tweets : [],
username: parsed.username || null,
complete: Boolean(parsed.complete),
source: parsed.source || null,
outputFile,
updatedAt: parsed.updatedAt || null,
};
}View on GitHub (pinned to 49907e53dc)
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
Example fix
// before twitter likes --resume likes.json # in-memory, file was created with --output // after twitter likes --resume likes.json --output /data/likes.json # same path as original run
Defensive patterns
Strategy: validation
Validate before calling
const parsed = JSON.parse(fs.readFileSync(resumePath, 'utf8'));
const resolvedOut = parsed.outputFile ? path.resolve(parsed.outputFile) : null;
if (resolvedOut !== expectedOutputFile)
throw new Error(`output mismatch: pass --output ${resolvedOut ?? '(none/in-memory)'}`); Try / catch
try {
await runLikes({ resume: resumePath, output: outFile });
} catch (e) {
if (/output mismatch/.test(e.message)) {
// re-run with the exact original --output path, or regenerate the resume
}
throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Resume file source mismatch: expected ${expected.source}, fo
- Resume file username mismatch: expected @${expected.username
- Resume file source mismatch: expected ${expected.source}, fo
- Resume file output mismatch: expected ${expected.outputFile
- Could not parse Twitter likes resume file ${filePath}: ${err
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/429f3b231e6a7cc7.
Report an issue: GitHub.