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

  1. Check `task-master show 5` to confirm the parent actually has the subtask you reference
  2. Fix the source ID to point at a parent that has subtasks
  3. If tasks.json is hand-edited and subtasks key is missing, restore the key or regenerate task files
  4. 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

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


AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29). Data as JSON: /api/errors/f7aa2ce1de38cb22. Report an issue: GitHub.