eyaltoledano/claude-task-master · error · MoveTaskError

SUBTASK_NOT_FOUND

SUBTASK_NOT_FOUND

Error message

Source subtask ${sourceId} not found

What it means

After finding the source parent, moveSubtaskToSubtask searches parent.subtasks for the subtask ID given in 'X.Y'. If the subtask is absent from the parent's subtasks array, it throws MoveTaskError with code SUBTASK_NOT_FOUND (message interpolates the full sourceId like '5.2').

Source

Thrown at scripts/modules/task-manager/move-task.js:250

			MOVE_ERROR_CODES.PARENT_TASK_NOT_FOUND,
			`Destination parent task with ID ${destParentId} not found`
		);
	}

	// Initialize subtasks arrays if they don't exist (based on commit fixes)
	if (!sourceParentTask.subtasks) {
		sourceParentTask.subtasks = [];
	}
	if (!destParentTask.subtasks) {
		destParentTask.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];

	if (sourceParentId === destParentId) {
		// Moving within the same parent
		if (destParentTask.subtasks.length > 0) {
			const destSubtaskIndex = destParentTask.subtasks.findIndex(
				(st) => st.id === destSubtaskId
			);
			if (destSubtaskIndex !== -1) {
				// Remove from old position
				sourceParentTask.subtasks.splice(sourceSubtaskIndex, 1);
				// Insert at new position (adjust index if moving within same array)
				const adjustedIndex =

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Run `task-master show <parentId>` to list the parent's actual subtask IDs and correct the ordinal
  2. Re-pull/sync tasks.json if another process modified it
  3. Remove empty parts of the source string (e.g. '5.' or '5,5.2' malformed entries) — parsing can yield NaN that matches nothing
  4. If the subtask was already moved, the operation is a no-op; skip it

Example fix

// before (task 5 has subtasks 1 and 2 only)
task-master move --from=5.3 --to=7.1
// after
task-master show 5   # subtasks: 5.1, 5.2
task-master move --from=5.2 --to=7.1
Defensive patterns

Strategy: validation

Validate before calling

function assertSourceSubtask(tasks, sourceId) {
  const [p, s] = String(sourceId).split('.').map((n) => parseInt(n, 10));
  const parent = tasks.find((t) => t.id === p);
  if (!parent?.subtasks?.some((st) => st.id === s)) {
    throw new Error(`Subtask ${sourceId} not found on parent ${p}`);
  }
}

Type guard

const subtaskExists = (tasks, sourceId) => {
  const [p, s] = sourceId.split('.').map(Number);
  return tasks.find((t) => t.id === p)?.subtasks?.some((st) => st.id === s) ?? false;
};

Try / catch

try {
  await moveTask(tasksPath, '5.2', '7.1', false, { projectRoot, tag });
} catch (err) {
  if (err.name === 'MoveTaskError' && err.code === 'SUBTASK_NOT_FOUND') {
    console.error('Check `task-master show 5` for the actual subtask IDs');
  } else throw err;
}

Prevention

When it happens

Trigger: Calling moveTask('5.3', '7.1') where task 5 exists but has no subtask with id 3; subtask was already moved/deleted; using a 1-based vs 0-based ID confusion (subtask IDs are stored as given, typically 1-based).

Common situations: Stale local tasks.json after a teammate moved the subtask; typo in the subtask ordinal; assuming subtasks auto-exist; hand-edited tasks.json where the subtasks array lost the entry.

Related errors


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