{"record":{"id":"dac237c5b33b6971","repo":"jackwener/OpenCLI","slug":"refusing-to-overwrite-existing-twitter-likes-outpu","errorCode":null,"errorMessage":"Refusing to overwrite existing Twitter likes output file: ${outputFile}","messagePattern":"Refusing to overwrite existing Twitter likes output file: (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/twitter/likes.js","lineNumber":280,"sourceCode":"      const url = ${JSON.stringify(buildUserByScreenNameQueryUrl(userByScreenNameQueryId, username))};\n      const resp = await fetch(url, { headers: ${headers}, credentials: 'include' });\n      if (!resp.ok) return null;\n      const d = await resp.json();\n      return d.data?.user?.result?.rest_id || null;\n    }`));\n        if (!userId) {\n            throw new CommandExecutionError(`Could not find user @${username}`);\n        }\n        const resumed = fetchAll ? readResumeFile(resumeFile, {\n            source: 'likes',\n            username,\n            outputFile: useOutputFile ? outputFile : null,\n        }) : null;\n        if (useOutputFile && resumed && resumed.count > 0 && !fs.existsSync(outputFile)) {\n            throw new CommandExecutionError(`Twitter likes output file is missing for resume state: ${outputFile}`);\n        }\n        if (useOutputFile && !resumed && fs.existsSync(outputFile)) {\n            throw new ArgumentError(`Refusing to overwrite existing Twitter likes output file: ${outputFile}`);\n        }\n        const allTweets = useOutputFile ? [] : (resumed?.tweets ? [...resumed.tweets] : []);\n        const jsonlState = useOutputFile ? loadJsonlArchiveState(outputFile) : null;\n        const seen = useOutputFile\n            ? jsonlState.seen\n            : new Set(allTweets.map((tweet) => tweet?.id).filter(Boolean));\n        if (useOutputFile && resumed && jsonlState.count !== resumed.count) {\n            throw new CommandExecutionError(`Twitter likes output file has ${jsonlState.count} record(s), expected resume count ${resumed.count}`);\n        }\n        let outputCount = useOutputFile ? jsonlState.count : 0;\n        let cursor = resumed?.cursor || null;\n        let lastRawResponse = null;\n        let pages = 0;\n        let exhausted = false;\n        // Runaway guard only; --limit/--all and cursor exhaustion control normal pagination.\n        while (pages < maxPages && (fetchAll || allTweets.length < limit)) {\n            pages += 1;\n            const currentCount = useOutputFile ? outputCount : allTweets.length;","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/likes.js#L262-L298","documentation":"ArgumentError thrown when no resume state exists but the requested output JSONL file already exists on disk. The library refuses to overwrite existing archives to protect previously fetched data from being clobbered by a fresh run.","triggerScenarios":"useOutputFile is true, readResumeFile returned null (no resume file), and fs.existsSync(outputFile) is true when reaching clis/twitter/likes.js:280.","commonSituations":"Re-running the same command twice without --resume; a previous run crashed after writing rows but the resume file was removed; intentionally re-collecting while pointing at last week's archive.","solutions":["Add the --resume flag to continue appending to the existing archive.","Choose a new --output file path for the fresh run.","Delete or rename the existing output file if you truly want to start over.","Back up the existing JSONL before deleting it."],"exampleFix":"// before\n$ cli twitter likes @user --output likes.jsonl  # likes.jsonl already exists\n// after\n$ cli twitter likes @user --output likes.jsonl --resume","handlingStrategy":"validation","validationCode":"const fs = require('node:fs');\nif (fs.existsSync(outputFile) && !wantsResume) {\n  outputFile = `likes-${Date.now()}.jsonl`; // pick a fresh name\n}","typeGuard":"null","tryCatchPattern":"try {\n  await cli.twitter.likes({ username, output: outputFile });\n} catch (e) {\n  if (/Refusing to overwrite/.test(e.message)) {\n    await cli.twitter.likes({ username, output: outputFile, resume: true });\n  } else throw e;\n}","preventionTips":["Use --resume when appending to an existing archive","Give each fresh run a unique output filename (timestamp suffix)","Check fs.existsSync(output) in your wrapper before invoking","Never manually delete the resume file without deciding the archive's fate"],"tags":["argument","filesystem","overwrite-protection"],"backgroundTag":"file-already-exists","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}