eyaltoledano/claude-task-master · error

Invalid subtask ID format: ${subtaskId}. In solo mode, subta

Error message

Invalid subtask ID format: ${subtaskId}. In solo mode, subtask ID must be in format "parentId.subtaskId" (e.g., "5.2").

What it means

When the remote/API bridge does not consume the update, file storage requires subtask IDs to contain a dot separating parent and subtask IDs. A dotless ID reaches this check only in solo/file mode and is rejected.

Source

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

			isMCP,
			outputFormat,
			report
		});

		// If remote handled it, return the result
		if (remoteResult) {
			return {
				updatedSubtask: { id: subtaskId },
				telemetryData: remoteResult.telemetryData,
				tagInfo: remoteResult.tagInfo
			};
		}
		// Otherwise fall through to file-based logic below
		// --- End BRIDGE ---

		// For file storage, validate the subtask ID format (must contain a dot)
		if (!subtaskId.includes('.')) {
			throw new Error(
				`Invalid subtask ID format: ${subtaskId}. In solo mode, subtask ID must be in format "parentId.subtaskId" (e.g., "5.2").`
			);
		}

		if (!fs.existsSync(tasksPath)) {
			throw new Error(`Tasks file not found at path: ${tasksPath}`);
		}

		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);

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Use the 'parentId.subtaskId' format, e.g. '5.2'
  2. Confirm whether your project uses API storage (then a plain task ID may be valid) or file storage
  3. For API-mode IDs, use the update-task path instead of update-subtask

Example fix

// before
await updateSubtaskById('3', prompt, options); // file storage requires a dot
// after
await updateSubtaskById('3.1', prompt, options);
Defensive patterns

Strategy: validation

Validate before calling

if (!subtaskId.includes('.')) {
  throw new Error(`Use parentId.subtaskId format, got: ${subtaskId}`);
}

Type guard

function isDottedSubtaskId(v) {
  return typeof v === 'string' && /^\d+\.\d+$/.test(v);
}

Try / catch

try {
  await updateSubtaskById(subtaskId, prompt, options);
} catch (err) {
  if (err.message.startsWith('Invalid subtask ID format')) {
    console.error('File storage requires dotted IDs like "5.2"');
  } else throw err;
}

Prevention

When it happens

Trigger: Calling updateSubtaskById('5', ...) in file-storage mode; using an API-style ID ('HAM-2611') against a local file-based project where the remote bridge returned no result.

Common situations: Copy-pasting API examples into a solo-mode project, forgetting the parent prefix, or a mixed setup where tryUpdateViaRemote silently fails and the file path runs.

Related errors


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