{"record":{"id":"95861b59db4dd25f","repo":"eyaltoledano/claude-task-master","slug":"generated-subtasks-must-have-unique-ids","errorCode":null,"errorMessage":"Generated subtasks must have unique ids","messagePattern":"Generated subtasks must have unique ids","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/modules/task-manager/scope-adjustment.js","lineNumber":456,"sourceCode":"\t\t\tpreserved: preservedSubtasks.length,\n\t\t\tgenerated: 0,\n\t\t\terror: error.message\n\t\t};\n\t}\n}\n\nfunction ensureSequentialSubtaskIds(subtasks) {\n\tif (!Array.isArray(subtasks) || subtasks.length === 0) {\n\t\treturn;\n\t}\n\n\tconst ids = subtasks.map((subtask) => subtask.id);\n\tif (ids.some((id) => !Number.isInteger(id) || id < 1)) {\n\t\tthrow new Error('Generated subtask ids must be positive integers');\n\t}\n\tconst uniqueIds = new Set(ids);\n\tif (uniqueIds.size !== ids.length) {\n\t\tthrow new Error('Generated subtasks must have unique ids');\n\t}\n\n\tconst sortedIds = [...uniqueIds].sort((a, b) => a - b);\n\tfor (let index = 0; index < sortedIds.length; index += 1) {\n\t\tif (sortedIds[index] !== index + 1) {\n\t\t\tthrow new Error(\n\t\t\t\t'Generated subtask ids must be sequential starting from 1'\n\t\t\t);\n\t\t}\n\t}\n}\n\n/**\n * Generates AI prompt for scope adjustment\n * @param {Object} task - The task to adjust\n * @param {string} direction - 'up' or 'down'\n * @param {string} strength - 'light', 'regular', or 'heavy'\n * @param {string} customPrompt - Optional custom instructions","sourceCodeStart":438,"sourceCodeEnd":474,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/scripts/modules/task-manager/scope-adjustment.js#L438-L474","documentation":"ensureSequentialSubtaskIds() also enforces that all generated subtask ids are distinct. It builds a Set of ids and compares size; duplicates mean the AI returned two subtasks sharing an id, which would collide in tasks.json. Thrown before any data is persisted, so the task file stays intact.","triggerScenarios":"scopeUpTask/scopeDownTask flows where the model returns duplicate ids such as [{id:1},{id:1},{id:2}], commonly when the model is asked for many subtasks and repeats an index, or when string vs number coercion masks duplicates ('1' vs 1 mapping to the same value after parsing).","commonSituations":"Large complexity-based expansions requesting 10+ subtasks from a weaker model, retries that merge old and new subtask lists without deduplication, or custom output parsing that doesn't dedupe.","solutions":["Retry the operation — regenerate the subtasks; duplicates are usually a one-off sampling artifact.","Deduplicate before validation if you control the pipeline: const seen = new Set(); subtasks.filter(s => !seen.has(s.id) && seen.add(s.id)).","Switch to a model that reliably produces schema-conformant JSON, or strengthen the prompt instruction to use strictly increasing ids.","Lower the requested subtask count (reduce complexity threshold) to make valid output more likely."],"exampleFix":"// before\n[{ \"id\": 1, \"title\": \"a\" }, { \"id\": 1, \"title\": \"b\" }]\n// after\n[{ \"id\": 1, \"title\": \"a\" }, { \"id\": 2, \"title\": \"b\" }]","handlingStrategy":"validation","validationCode":"function hasNoDuplicateIds(subtasks) {\n  const ids = subtasks.map((s) => s.id);\n  return new Set(ids).size === ids.length;\n}\nif (!hasNoDuplicateIds(generated.subtasks)) {\n  const seen = new Set();\n  generated.subtasks = generated.subtasks.filter((s) => !seen.has(s.id) && seen.add(s.id));\n}","typeGuard":"function idsAreUnique(subtasks) {\n  const ids = subtasks.map((s) => s.id);\n  return ids.every((id, i) => ids.indexOf(id) === i) && ids.every((id) => Number.isInteger(id) && id >= 1);\n}","tryCatchPattern":"try {\n  await scopeDownTask([taskId], strength);\n} catch (err) {\n  if (err.message.includes('must have unique ids')) {\n    console.error('Duplicate subtask IDs from AI generation — rerun the scope operation');\n  } else throw err;\n}","preventionTips":["Deduplicate AI output by id before any persistence step","Request fewer subtasks per generation to reduce duplicate sampling","Strengthen prompts with explicit 'unique strictly increasing integer ids' instructions","Retain a JSON schema for subtask output and validate against it before use"],"tags":["validation","duplicate-ids","llm-output"],"backgroundTag":"duplicate-identifier","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}