eyaltoledano/claude-task-master · error
Generated subtasks must have unique ids
Error message
Generated subtasks must have unique ids
What it means
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.
Source
Thrown at scripts/modules/task-manager/scope-adjustment.js:456
preserved: preservedSubtasks.length,
generated: 0,
error: error.message
};
}
}
function ensureSequentialSubtaskIds(subtasks) {
if (!Array.isArray(subtasks) || subtasks.length === 0) {
return;
}
const ids = subtasks.map((subtask) => subtask.id);
if (ids.some((id) => !Number.isInteger(id) || id < 1)) {
throw new Error('Generated subtask ids must be positive integers');
}
const uniqueIds = new Set(ids);
if (uniqueIds.size !== ids.length) {
throw new Error('Generated subtasks must have unique ids');
}
const sortedIds = [...uniqueIds].sort((a, b) => a - b);
for (let index = 0; index < sortedIds.length; index += 1) {
if (sortedIds[index] !== index + 1) {
throw new Error(
'Generated subtask ids must be sequential starting from 1'
);
}
}
}
/**
* Generates AI prompt for scope adjustment
* @param {Object} task - The task to adjust
* @param {string} direction - 'up' or 'down'
* @param {string} strength - 'light', 'regular', or 'heavy'
* @param {string} customPrompt - Optional custom instructionsView on GitHub (pinned to c0c98d367c)
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.
Example fix
// before
[{ "id": 1, "title": "a" }, { "id": 1, "title": "b" }]
// after
[{ "id": 1, "title": "a" }, { "id": 2, "title": "b" }] Defensive patterns
Strategy: validation
Validate before calling
function hasNoDuplicateIds(subtasks) {
const ids = subtasks.map((s) => s.id);
return new Set(ids).size === ids.length;
}
if (!hasNoDuplicateIds(generated.subtasks)) {
const seen = new Set();
generated.subtasks = generated.subtasks.filter((s) => !seen.has(s.id) && seen.add(s.id));
} Type guard
function idsAreUnique(subtasks) {
const ids = subtasks.map((s) => s.id);
return ids.every((id, i) => ids.indexOf(id) === i) && ids.every((id) => Number.isInteger(id) && id >= 1);
} Try / catch
try {
await scopeDownTask([taskId], strength);
} catch (err) {
if (err.message.includes('must have unique ids')) {
console.error('Duplicate subtask IDs from AI generation — rerun the scope operation');
} else throw err;
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- Generated object does not match schema: ${validationError.me
- Generated subtask ids must be positive integers
- Generated subtask ids must be sequential starting from 1
- MFA_VERIFICATION_FAILED
- Failed to initialize services: ${(error as Error).message}
AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29).
Data as JSON: /api/errors/95861b59db4dd25f.
Report an issue: GitHub.