eyaltoledano/claude-task-master · error

Subtask ${subtaskId} not found in parent task ${parentId}

Error message

Subtask ${subtaskId} not found in parent task ${parentId}

What it means

updateSingleTaskStatus looks up the subtask by numeric ID within the parent task's subtasks array and throws when no subtask with that ID exists. It is thrown after confirming the parent task exists and has subtasks, so it specifically means the subtask ID itself does not match any entry.

Source

Thrown at scripts/modules/task-manager/update-single-task-status.js:46

	if (taskIdInput.includes('.')) {
		const [parentId, subtaskId] = taskIdInput
			.split('.')
			.map((id) => parseInt(id, 10));

		// Find the parent task
		const parentTask = data.tasks.find((t) => t.id === parentId);
		if (!parentTask) {
			throw new Error(`Parent task ${parentId} not found`);
		}

		// Find the subtask
		if (!parentTask.subtasks) {
			throw new Error(`Parent task ${parentId} has no subtasks`);
		}

		const subtask = parentTask.subtasks.find((st) => st.id === subtaskId);
		if (!subtask) {
			throw new Error(
				`Subtask ${subtaskId} not found in parent task ${parentId}`
			);
		}

		// Update the subtask status
		const oldStatus = subtask.status || 'pending';
		subtask.status = newStatus;

		log(
			'info',
			`Updated subtask ${parentId}.${subtaskId} status from '${oldStatus}' to '${newStatus}'`
		);

		// Check if all subtasks are done (if setting to 'done')
		if (
			newStatus.toLowerCase() === 'done' ||
			newStatus.toLowerCase() === 'completed'
		) {

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Run 'task-master list' or read tasks.json to confirm the subtask ID exists under the parent
  2. Verify you are operating on the correct tag/context (subtasks differ per tag)
  3. Re-check that the ID is parentId.subtaskId and the subtask part matches an existing subtask id

Example fix

// before
await setTaskStatus('5.3', 'done', tasksPath);
// after
const parent = data.tasks.find(t => t.id === 5);
if (!parent?.subtasks?.some(s => s.id === 3)) {
  throw new Error('Subtask 5.3 does not exist; check list output first');
}
await setTaskStatus('5.3', 'done', tasksPath);
Defensive patterns

Strategy: validation

Validate before calling

const [pid, sid] = String(id).split('.').map(Number);
const parent = data.tasks.find(t => t.id === pid);
if (!parent?.subtasks?.some(s => s.id === sid)) {
  throw new Error(`Subtask ${id} does not exist; check task-master list`);
}

Type guard

function subtaskExists(tasks, id) {
  const [p, s] = String(id).split('.').map(Number);
  return tasks.some(t => t.id === p && Array.isArray(t.subtasks) && t.subtasks.some(st => st.id === s));
}

Try / catch

try {
  await setTaskStatus(id, 'done', tasksPath);
} catch (err) {
  if (String(err.message).includes('not found in parent task')) {
    console.error(`Subtask ${id} missing — verify with task-master list`);
  } else throw err;
}

Prevention

When it happens

Trigger: Calling setTaskStatus (or updateSingleTaskStatus) with an ID like '5.2' where parent 5 exists and has subtasks, but no subtask with id 2; or passing a subtask ID that was already deleted.

Common situations: Stale IDs from an old task list, off-by-one mistakes assuming subtasks are 0-indexed (they are 1-indexed by default), or querying a different tag where the parent's subtasks differ.

Related errors


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