jackwener/OpenCLI · error · ArgumentError
Resume file source mismatch: expected ${expected.source}, fo
Error message
Resume file source mismatch: expected ${expected.source}, found ${parsed.source || 'unknown'} What it means
When an `expected` descriptor is supplied, readResumeFile checks that the resume file's `source` field matches the current run's source and throws this ArgumentError on mismatch. This prevents resuming a likes run from a file produced by a different collection source (which would produce inconsistent cursors/results).
Source
Thrown at clis/twitter/likes.js:141
let parsed;
try {
parsed = JSON.parse(fs.readFileSync(filePath, 'utf8'));
}
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,View on GitHub (pinned to 49907e53dc)
Solutions
- Check the file's `source` field and either run with the source it was created for, or regenerate the resume file with the intended source
- Delete the mismatched resume file and start a fresh run
- Pin/align the library version between the run that created the file and the resuming run
- If the source label is legitimately the same, fix a corrupted `source` field manually before resuming
Example fix
// before (mismatch)
{"source": "favorites", ...} // resuming a "likes" run
// after
{"source": "likes", ...} // or start a fresh likes run Defensive patterns
Strategy: validation
Validate before calling
const parsed = JSON.parse(fs.readFileSync(resumePath, 'utf8'));
if (parsed.source !== expectedSource) throw new Error(`source mismatch: ${parsed.source} != ${expectedSource}`); Try / catch
try {
await runLikes({ resume: resumePath, source: expectedSource });
} catch (e) {
if (/Resume file source mismatch/.test(e.message)) {
// regenerate a resume file for this source or run with the file's original source
}
throw e;
} Prevention
- Use one resume file per source type; never share across commands
- Keep (source, username) in resume filenames
- Align library versions between creating and resuming runs
- Inspect the file's `source` field before resuming
When it happens
Trigger: Running `twitter likes` with --resume plus matching expectations where parsed.source differs from expected.source — e.g. resuming a file generated for a different source type (likes vs another timeline source) or from an older/newer CLI variant that wrote a different source label.
Common situations: Reusing one resume file across different commands or source types; a library upgrade renamed/changed the source identifier; copy-pasting a resume file from a colleague's run that used a different source option.
Related errors
- Resume file username mismatch: expected @${expected.username
- Resume file output mismatch: expected ${expected.outputFile
- 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/9206017fa93491f5.
Report an issue: GitHub.