{"record":{"id":"bb6aa22c661d7d22","repo":"jackwener/OpenCLI","slug":"resume-file-username-mismatch-expected-expecte","errorCode":null,"errorMessage":"Resume file username mismatch: expected @${expected.username}, found @${parsed.username || 'unknown'}","messagePattern":"Resume file username mismatch: expected @(.+?), found @(.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/twitter/likes.js","lineNumber":143,"sourceCode":"        parsed = JSON.parse(fs.readFileSync(filePath, 'utf8'));\n    }\n    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,","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/likes.js#L125-L161","documentation":"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.","triggerScenarios":"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'.","commonSituations":"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.","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"],"exampleFix":"// before\ntwitter likes --username userB --resume likes-userA.json\n// after\ntwitter likes --username userA --resume likes-userA.json\n// or fresh: twitter likes --username userB (new resume file)","handlingStrategy":"validation","validationCode":"const parsed = JSON.parse(fs.readFileSync(resumePath, 'utf8'));\nif (String(parsed.username || '').toLowerCase() !== targetUsername.toLowerCase())\n  throw new Error(`resume file is for @${parsed.username}, not @${targetUsername}`);","typeGuard":null,"tryCatchPattern":"try {\n  await runLikes({ resume: resumePath, username: user });\n} catch (e) {\n  if (/username mismatch/.test(e.message)) {\n    resumePath = `likes-${user}.json`; // switch to the correct per-user file or start fresh\n  } else throw e;\n}","preventionTips":["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"],"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"}