eyaltoledano/claude-task-master · error · Error
Subtask ${subtaskId} not found in parent task ${parentId}
Error message
Subtask ${subtaskId} not found in parent task ${parentId} What it means
After the parent task is located, updateSubtaskStatusInFile searches parentTask.subtasks for a subtask whose id matches the numeric portion after the dot. If no subtask matches, this error is thrown. The parent exists but the specific subtask does not, so the write is aborted.
Source
Thrown at packages/tm-core/src/modules/storage/adapters/file-storage/file-storage.ts:539
// Find the parent task
const parentTaskIndex = tasks.findIndex(
(t) => String(t.id) === String(parentId)
);
if (parentTaskIndex === -1) {
throw new Error(`Parent task ${parentId} not found`);
}
const parentTask = tasks[parentTaskIndex];
// Find the subtask within the parent task
const subtaskIndex = parentTask.subtasks.findIndex(
(st) => st.id === subtaskNumericId || String(st.id) === subId
);
if (subtaskIndex === -1) {
throw new Error(
`Subtask ${subtaskId} not found in parent task ${parentId}`
);
}
const oldStatus = parentTask.subtasks[subtaskIndex].status || 'pending';
if (oldStatus === newStatus) {
return {
success: true,
oldStatus,
newStatus,
taskId: subtaskId
};
}
const now = new Date().toISOString();
// Update the subtask status
parentTask.subtasks[subtaskIndex] = {View on GitHub (pinned to c0c98d367c)
Solutions
- Load the parent task and inspect its subtasks array to confirm the subtask ID before updating.
- Verify the dotted ID is correct: parentId.subtaskId with a positive integer subtask number.
- Check the subtask is not under a different parent or a different tag.
- Re-create the subtask if it was deleted and the status update is still needed.
Example fix
// before
await storage.updateTaskStatus('5.9', 'done');
// after
const tasks = await storage.getTasks(tag);
const parent = tasks.find((t) => String(t.id) === '5');
if (!parent?.subtasks?.some((s) => String(s.id) === '9')) {
throw new Error('Subtask 5.9 does not exist');
}
await storage.updateTaskStatus('5.9', 'done', tag); Defensive patterns
Strategy: validation
Validate before calling
const tasks = await storage.getTasks(tag);
const [pid, sid] = subtaskId.split('.');
const parent = tasks.find((t) => String(t.id) === pid);
if (!parent?.subtasks?.some((s) => String(s.id) === sid)) {
throw new Error(`Subtask ${subtaskId} does not exist`);
} Type guard
function findSubtask(parent: Task, subId: string): Subtask | undefined {
return parent.subtasks?.find((s) => String(s.id) === subId.trim());
} Try / catch
try {
await storage.updateTaskStatus('5.2', 'done', tag);
} catch (err) {
if (err instanceof Error && /Subtask .* not found in parent/.test(err.message)) {
console.warn('Subtask missing; refreshing task list');
return;
}
throw err;
} Prevention
- Read subtask numbers from the parent's subtasks array rather than hardcoding them.
- Re-fetch tasks after any operation that can renumber or remove subtasks.
- Confirm both halves of the dotted ID before calling status updates.
- Watch for tag switches between listing and updating subtasks.
When it happens
Trigger: updateTaskStatus('5.9', 'done') where task 5 exists but has no subtask 9; using a stale subtask number after subtasks were renumbered or removed; passing the full subtask object id when only the numeric part is expected; subtask stored under a different parent.
Common situations: Automation referencing subtasks deleted during cleanup; tasks.json edited by hand dropping subtasks; migration between tags where subtask numbering differs; typos in the subtask portion of the dotted ID.
Related errors
- Parent task ${parentId} not found
- Tag ${tag} not found
- Tag ${oldTag} not found
- PARENT_TASK_NOT_FOUND
- SUBTASK_NOT_FOUND
AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29).
Data as JSON: /api/errors/76914118eeb14eb0.
Report an issue: GitHub.