{"record":{"id":"994c628977f191cc","repo":"jackwener/OpenCLI","slug":"refusing-to-overwrite-existing-pixiv-download-p","errorCode":null,"errorMessage":"Refusing to overwrite existing Pixiv download: ${plan.finalPath}","messagePattern":"Refusing to overwrite existing Pixiv download: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/pixiv/bookmark-download.js","lineNumber":113,"sourceCode":"  try {\n    fs.mkdirSync(parent, { recursive: true });\n    staging = fs.mkdtempSync(path.join(parent, `.opencli-${plan.illustId}-`));\n    for (const file of plan.files) {\n      const destination = path.join(staging, file.filename);\n      const result = await httpDownload(file.url, destination, {\n        cookies,\n        headers: { Referer: 'https://www.pixiv.net/' },\n        timeout: 60000,\n        includeContentType: true,\n      });\n      validateImageDownload(result, file);\n      const stat = fs.lstatSync(destination);\n      if (stat.isSymbolicLink() || !stat.isFile() || stat.size <= 0) {\n        throw new CommandExecutionError(`Pixiv image download did not create a valid file: ${file.filename}`);\n      }\n    }\n    if (pixivPathEntryExists(plan.finalPath)) {\n      throw new CommandExecutionError(`Refusing to overwrite existing Pixiv download: ${plan.finalPath}`);\n    }\n    fs.renameSync(staging, plan.finalPath);\n    return plan.finalPath;\n  } catch (error) {\n    if (staging) {\n      try { fs.rmSync(staging, { recursive: true, force: true }); } catch {}\n    }\n    for (const directory of plan.createdDirs) {\n      try { fs.rmdirSync(directory); } catch {}\n    }\n    if (error instanceof CommandExecutionError) throw error;\n    throw new CommandExecutionError(`Pixiv illustration ${plan.illustId} download failed: ${error?.message || error}`);\n  }\n}\n\nfunction cleanupPlan(plan) {\n  if (plan.kind === 'novel') {\n    cleanupNovelFile(plan);","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/pixiv/bookmark-download.js#L95-L131","documentation":"commitIllustPlan refuses to clobber an existing path: before renaming the staged download into place it checks pixivPathEntryExists(plan.finalPath). This CommandExecutionError is thrown when a file or directory already exists at the final destination, protecting prior downloads from silent overwrite. The whole illustration is rolled back (staging removed, created dirs cleaned).","triggerScenarios":"plan.finalPath already exists in the output root when commitIllustPlan finishes staging, i.e. a previous run of bookmark-download already saved this artwork at that path.","commonSituations":"Running bookmark-download twice with the same --output directory; two parallel download processes racing to save the same bookmark; a leftover partial download from a crashed earlier run; an unrelated file coincidentally named like the artwork in the output folder.","solutions":["Use a fresh or empty --output directory for the run","Delete or move the existing file at plan.finalPath if you intend to re-download it","Skip artworks whose files already exist before building the plan","Avoid running two bookmark-download processes concurrently against the same output root","Check for orphaned partial downloads from previous failed runs"],"exampleFix":"// before: unconditional re-run into same dir\npixiv bookmark-download --page 1 --output ./pixiv-downloads/bookmarks\n// after: check first, then download only missing items\nfor f in wantedIds; do [ -e \"out/$f.jpg\" ] || pixiv bookmark-download --page 1 --output ./pixiv-downloads/bookmarks; done","handlingStrategy":"validation","validationCode":"if (fs.existsSync(plan.finalPath)) {\n  console.warn(`Skipping existing download: ${plan.finalPath}`);\n  return plan.finalPath;\n}","typeGuard":"function isFreeForWrite(p) {\n  return !fs.existsSync(p) && !fs.existsSync(p + '.part');\n}","tryCatchPattern":"try {\n  return commitIllustPlan(plan, cookies);\n} catch (err) {\n  if (/Refusing to overwrite/.test(err.message)) {\n    console.warn(`Already downloaded: ${plan.finalPath}`);\n    return plan.finalPath; // treat as success/idempotent\n  }\n  throw err;\n}","preventionTips":["Check pixivPathEntryExists (or fs.existsSync) for every target before starting a run","Use a fresh output directory per run or versioned subdirectories","Never run two bookmark-download processes against the same output root","Clean up orphaned partial downloads from crashed runs"],"tags":["pixiv","download","filesystem","collision","overwrite-protection"],"backgroundTag":"file-already-exists","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}