eyaltoledano/claude-task-master · error · MoveTaskError
PARENT_TASK_NO_SUBTASKS
PARENT_TASK_NO_SUBTASKS
Error message
Source parent task ${sourceParentId} has no subtasks What it means
When promoting a subtask to a task, after confirming the source parent exists, moveSubtaskToTask checks that the parent actually has a subtasks array. If sourceParentTask.subtasks is undefined/null (task has never had subtasks), it throws MoveTaskError with code PARENT_TASK_NO_SUBTASKS.
Source
Thrown at scripts/modules/task-manager/move-task.js:317
function moveSubtaskToTask(tasks, sourceId, destinationId) {
// Parse source ID
const [sourceParentId, sourceSubtaskId] = sourceId
.split('.')
.map((id) => parseInt(id, 10));
const destTaskId = parseInt(destinationId, 10);
// Find source parent and destination task
const sourceParentTask = tasks.find((t) => t.id === sourceParentId);
if (!sourceParentTask) {
throw new MoveTaskError(
MOVE_ERROR_CODES.PARENT_TASK_NOT_FOUND,
`Source parent task with ID ${sourceParentId} not found`
);
}
if (!sourceParentTask.subtasks) {
throw new MoveTaskError(
MOVE_ERROR_CODES.PARENT_TASK_NO_SUBTASKS,
`Source parent task ${sourceParentId} has no subtasks`
);
}
// Find source subtask
const sourceSubtaskIndex = sourceParentTask.subtasks.findIndex(
(st) => st.id === sourceSubtaskId
);
if (sourceSubtaskIndex === -1) {
throw new MoveTaskError(
MOVE_ERROR_CODES.SUBTASK_NOT_FOUND,
`Source subtask ${sourceId} not found`
);
}
const sourceSubtask = sourceParentTask.subtasks[sourceSubtaskIndex];
View on GitHub (pinned to c0c98d367c)
Solutions
- Check `task-master show 5` to confirm the parent actually has the subtask you reference
- Fix the source ID to point at a parent that has subtasks
- If tasks.json is hand-edited and subtasks key is missing, restore the key or regenerate task files
- Guard programmatically: check Array.isArray(task.subtasks) && task.subtasks.some(s => s.id === subId) before calling moveTask
Example fix
// before (task 5 has no subtasks) task-master move --from=5.2 --to=9 // after task-master show 5 # no subtasks; the subtask is under 6: task-master move --from=6.2 --to=9
Defensive patterns
Strategy: type-guard
Validate before calling
function assertParentHasSubtasks(tasks, sourceId) {
const parentId = parseInt(String(sourceId).split('.')[0], 10);
const parent = tasks.find((t) => t.id === parentId);
if (!parent) throw new Error(`Parent ${parentId} not found`);
if (!Array.isArray(parent.subtasks)) throw new Error(`Parent ${parentId} has no subtasks`);
} Type guard
function parentWithSubtasks(task) {
return typeof task === 'object' && task !== null && Array.isArray(task.subtasks) && task.subtasks.length > 0;
} Try / catch
try {
await moveTask(tasksPath, '5.2', '9', false, { projectRoot, tag });
} catch (err) {
if (err.name === 'MoveTaskError' && err.code === 'PARENT_TASK_NO_SUBTASKS') {
console.error(`Task has no subtasks — verify with 'task-master show' before moving '5.x'`);
} else throw err;
} Prevention
- Check `task-master show <parentId>` shows subtasks before referencing 'X.Y'
- Validate with Array.isArray(task.subtasks) && subtasks.some(s => s.id === n) in scripts
- Don't assume a subtask ordinal belongs to a given parent — IDs are local to each parent
- Restore a missing subtasks key if tasks.json was hand-edited
When it happens
Trigger: Calling moveTask('5.2', '9') where task 5 exists but has no subtasks property at all — note a task with an empty [] array passes this check and fails later with SUBTASK_NOT_FOUND; the '.2' subtask part references a subtask on a childless task.
Common situations: Copy/paste or scripted ID lists pointing a subtask ID at the wrong parent; task's subtasks were all moved away and the (now empty) handling differs by code path; hand-edited tasks.json removed the subtasks key entirely.
Related errors
- PARENT_TASK_NOT_FOUND
- Invalid iterations: ${iterations}. Must be a positive intege
- Invalid format: ${options.format}. Valid formats are: text,
- Invalid subtask ID format: ${subtaskId}. Expected format: pa
- Invalid subtask ID: ${subId}. Subtask ID must be a positive
AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29).
Data as JSON: /api/errors/f7aa2ce1de38cb22.
Report an issue: GitHub.