eyaltoledano/claude-task-master · error

Invalid subtask ID format: ${subtaskId}. Both parent ID and

Error message

Invalid subtask ID format: ${subtaskId}. Both parent ID and subtask ID must be positive integers.

What it means

After splitting the dotted ID, both halves are parsed as integers; if either is NaN or <= 0 the format is rejected. This catches IDs like '5.0', 'a.2', '5.-1', or '5.2.3' leftovers that fail parseInt.

Source

Thrown at scripts/modules/task-manager/update-subtask-by-id.js:150

		const data = readJSON(tasksPath, projectRoot, tag);
		if (!data || !data.tasks) {
			throw new Error(
				`No valid tasks found in ${tasksPath}. The file may be corrupted or have an invalid format.`
			);
		}

		const [parentIdStr, subtaskIdStr] = subtaskId.split('.');
		const parentId = parseInt(parentIdStr, 10);
		const subtaskIdNum = parseInt(subtaskIdStr, 10);

		if (
			Number.isNaN(parentId) ||
			parentId <= 0 ||
			Number.isNaN(subtaskIdNum) ||
			subtaskIdNum <= 0
		) {
			throw new Error(
				`Invalid subtask ID format: ${subtaskId}. Both parent ID and subtask ID must be positive integers.`
			);
		}

		const parentTask = data.tasks.find((task) => task.id === parentId);
		if (!parentTask) {
			throw new Error(
				`Parent task with ID ${parentId} not found. Please verify the task ID and try again.`
			);
		}

		if (!parentTask.subtasks || !Array.isArray(parentTask.subtasks)) {
			throw new Error(`Parent task ${parentId} has no subtasks.`);
		}

		const subtaskIndex = parentTask.subtasks.findIndex(
			(st) => st.id === subtaskIdNum
		);

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Ensure both segments are positive integers, e.g. '5.2'
  2. Validate with a regex like /^\d+\.\d+$/ before calling
  3. Use API-style IDs only via the remote bridge/update-task path

Example fix

// before
await updateSubtaskById('5.0', prompt, options); // 0 is invalid
// after
if (!/^\d+\.\d+$/.test(subtaskId)) throw new Error(`Bad subtask ID: ${subtaskId}`);
await updateSubtaskById('5.1', prompt, options);
Defensive patterns

Strategy: validation

Validate before calling

const m = /^\d+\.\d+$/.exec(subtaskId);
if (!m || Number(subtaskId.split('.')[0]) <= 0 || Number(subtaskId.split('.')[1]) <= 0) {
  throw new Error(`Subtask ID must be parentId.subtaskId with positive integers: ${subtaskId}`);
}

Type guard

function isPositiveDottedId(v) {
  if (typeof v !== 'string') return false;
  const [a, b] = v.split('.');
  return Number.isInteger(+a) && +a > 0 && Number.isInteger(+b) && +b > 0;
}

Try / catch

try {
  await updateSubtaskById(subtaskId, prompt, options);
} catch (err) {
  if (err.message.includes('must be positive integers')) {
    console.error(`Fix ID segments (no 0/negatives/letters): ${subtaskId}`);
  } else throw err;
}

Prevention

When it happens

Trigger: Passing '0.2' or '5.0', alphabetic segments ('HAM.1' in file mode), or malformed strings with extra segments.

Common situations: Mixing API-style IDs with file-mode calls, off-by-one using subtask index 0, template variables left unexpanded ('${parentId}.2').

Related errors


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