{"record":{"id":"e1da4bf812e1337f","repo":"jackwener/OpenCLI","slug":"pixiv-bookmark-archive-contains-a-duplicate-downlo","errorCode":null,"errorMessage":"Pixiv bookmark archive contains a duplicate download target: ${target}","messagePattern":"Pixiv bookmark archive contains a duplicate download target: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/pixiv/bookmark-download.js","lineNumber":181,"sourceCode":"    if (rows.length === 0) {\n      throw new EmptyResultError('pixiv bookmark-download', 'No Pixiv bookmarks matched the requested page.');\n    }\n\n    // Complete every API/schema/collision check before creating a file.\n    const plans = [];\n    for (const row of rows) {\n      if (type === 'novel') {\n        const body = await fetchNovelForDownload(page, row.novel_id);\n        plans.push({ ...prepareNovelFile(body, path.join(outputRoot, 'novel'), format), row });\n      } else {\n        plans.push({ ...await prepareIllustPlan(page, row, outputRoot), row });\n      }\n    }\n    const targets = new Set();\n    for (const plan of plans) {\n      const target = plan.kind === 'novel' ? plan.destPath : plan.finalPath;\n      if (targets.has(target)) {\n        throw new CommandExecutionError(`Pixiv bookmark archive contains a duplicate download target: ${target}`);\n      }\n      targets.add(target);\n    }\n\n    let cookies = '';\n    if (type === 'illust') {\n      let rawCookies;\n      try {\n        rawCookies = await page.getCookies({ domain: 'pixiv.net' });\n      } catch (error) {\n        throw new CommandExecutionError(`Pixiv cookie lookup failed: ${error?.message || error}`);\n      }\n      if (!Array.isArray(rawCookies)) {\n        throw new CommandExecutionError('Pixiv cookie lookup returned malformed data');\n      }\n      try {\n        cookies = formatCookieHeader(rawCookies);\n      } catch (error) {","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/pixiv/bookmark-download.js#L163-L199","documentation":"After building a download plan for every bookmark row, commitIllustPlan's caller ensures no two plans target the same destination path (novels use plan.destPath, illustrations use plan.finalPath). This CommandExecutionError is thrown when the Set of targets detects a duplicate, because two files would race to write the same path and one would clobber the other.","triggerScenarios":"Two or more rows on the requested bookmark page(s) resolve to the same download target — e.g. the same artwork bookmarked/appearing twice, or filename generation colliding for two different artworks (same id+filename derivation).","commonSituations":"A bookmark page listing the same illust twice (e.g. via different bookmark tags); output naming scheme too coarse (filename omits page/part index for multi-page works); user-supplied --output layout flattening distinct items to one path; combining page ranges so rows overlap.","solutions":["Deduplicate rows by illustId/novelId before building plans","Include a unique component (illust id, page index) in destPath/finalPath generation so distinct items never collide","Remove duplicate bookmarks on Pixiv, or restrict the page range so rows don't overlap","Check whether a custom --output naming option causes collisions and adjust it"],"exampleFix":"// before: plans may contain dupes\nconst plans = rows.map(buildPlan);\n// after: dedupe by id first\nconst seen = new Set();\nconst plans = rows.filter(r => !seen.has(r.id) && seen.add(r.id)).map(buildPlan);","handlingStrategy":"validation","validationCode":"const targets = new Set();\nfor (const plan of plans) {\n  const t = plan.kind === 'novel' ? plan.destPath : plan.finalPath;\n  if (targets.has(t)) throw new Error(`duplicate target ${t}`);\n  targets.add(t);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await runBookmarkArchive(rows, kwargs);\n} catch (err) {\n  if (/duplicate download target/.test(err.message)) {\n    const dup = err.message.split(': ')[1];\n    console.warn(`Deduplicating and retrying without ${dup}`);\n    return runBookmarkArchive(dedupeRows(rows), kwargs);\n  }\n  throw err;\n}","preventionTips":["Deduplicate bookmark rows by illustId/novelId before planning","Make finalPath/destPath include a unique id component","Avoid overlapping page ranges across runs","Review custom --output naming schemes for collisions"],"tags":["pixiv","bookmarks","collision","deduplication"],"backgroundTag":"duplicate-download-target","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}