jackwener/OpenCLI · error · ArgumentError
Resume file username mismatch: expected @${expected.username
Error message
Resume file username mismatch: expected @${expected.username}, found @${parsed.username || 'unknown'} What it means
readResumeFile compares the resume file's `username` (case-insensitively) against the expected username for the current run and throws this ArgumentError on mismatch. This stops you from resuming another account's likes run with the wrong cursor context, which would corrupt results.
Source
Thrown at clis/twitter/likes.js:143
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,
outputFile,
updatedAt: parsed.updatedAt || null,View on GitHub (pinned to 49907e53dc)
Solutions
- Resume with the same username the file was created for, or delete the file and start a fresh run for the new user
- Keep one resume file per (source, username) pair and name them accordingly
- Regenerate the resume file if the username field is missing or corrupted
- Verify the --username/expected argument you pass matches the original run
Example fix
// before twitter likes --username userB --resume likes-userA.json // after twitter likes --username userA --resume likes-userA.json // or fresh: twitter likes --username userB (new resume file)
Defensive patterns
Strategy: validation
Validate before calling
const parsed = JSON.parse(fs.readFileSync(resumePath, 'utf8'));
if (String(parsed.username || '').toLowerCase() !== targetUsername.toLowerCase())
throw new Error(`resume file is for @${parsed.username}, not @${targetUsername}`); Try / catch
try {
await runLikes({ resume: resumePath, username: user });
} catch (e) {
if (/username mismatch/.test(e.message)) {
resumePath = `likes-${user}.json`; // switch to the correct per-user file or start fresh
} else throw e;
} Prevention
- Name resume files per user (likes-<user>.json) and never reuse across accounts
- Verify the --username argument matches the original run
- Check parsed.username before resuming
- Start a fresh run whenever the target account changes
When it happens
Trigger: Running `twitter likes --resume <file>` while targeting user @B when the file records @A (parsed.username differs from expected.username, case-insensitive), or the file's username field is missing/blank so it resolves to 'unknown'.
Common situations: Switching target accounts between runs while reusing the same resume file; resuming a file saved from a different profile; a resume file whose username field was lost or stripped during manual editing.
Related errors
- Resume file source mismatch: expected ${expected.source}, fo
- 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/bb6aa22c661d7d22.
Report an issue: GitHub.