eyaltoledano/claude-task-master · error

All subtasks for task ${taskId} are already completed. Nothi

Error message

All subtasks for task ${taskId} are already completed. Nothing to do.

What it means

startWorkflow() maps the provided subtasks to workflow subtasks and looks for the first one whose status is not 'completed'. If every subtask is already completed (findIndex returns -1), there is nothing for the TDD loop to do, so the service throws instead of creating an empty workflow. Any subtask with status 'done' is treated as completed.

Source

Thrown at packages/tm-core/src/modules/workflow/services/workflow.service.ts:197

		await gitAdapter.ensureCleanWorkingTree();

		// Parse subtasks to WorkflowContext format
		const workflowSubtasks: SubtaskInfo[] = subtasks.map((st) => ({
			id: st.id,
			title: st.title,
			status: st.status === 'done' ? 'completed' : 'pending',
			attempts: 0,
			maxAttempts: st.maxAttempts || maxAttempts
		}));

		// Find the first incomplete subtask to resume from
		const firstIncompleteIndex = workflowSubtasks.findIndex(
			(st) => st.status !== 'completed'
		);

		// If all subtasks are already completed, throw an error
		if (firstIncompleteIndex === -1) {
			throw new Error(
				`All subtasks for task ${taskId} are already completed. Nothing to do.`
			);
		}

		// Create workflow context, starting from first incomplete subtask
		const context: WorkflowContext = {
			taskId,
			subtasks: workflowSubtasks,
			currentSubtaskIndex: firstIncompleteIndex,
			tag,
			errors: [],
			metadata: {
				startedAt: new Date().toISOString(),
				taskTitle,
				resumedFromSubtask:
					firstIncompleteIndex > 0
						? workflowSubtasks[firstIncompleteIndex].id
						: undefined

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Verify the task's subtask statuses; if truly done, no workflow is needed — mark the main task done instead of starting a workflow.
  2. If statuses are wrong, reset the relevant subtasks to 'pending' before calling startWorkflow.
  3. Pass the full unfiltered subtask list; ensure you are not accidentally passing only completed subtasks.
  4. If a workflow already tracked this task, use resumeWorkflow() to reach the FINALIZE phase rather than calling startWorkflow again.

Example fix

// before
const subtasks = task.subtasks; // all marked 'done'
await workflowService.startWorkflow({ taskId, taskTitle, subtasks });
// after
const actionable = task.subtasks.filter((st) => st.status !== 'done');
if (actionable.length === 0) {
  await taskService.setTaskStatus(taskId, 'done'); // nothing to do
} else {
  await workflowService.startWorkflow({ taskId, taskTitle, subtasks: task.subtasks });
}
Defensive patterns

Strategy: validation

Validate before calling

const pending = subtasks.filter((st) => st.status !== 'done');
if (pending.length === 0) {
  // nothing to do: mark task done or bail out early
  return; // or await taskService.setTaskStatus(taskId, 'done');
}
await workflowService.startWorkflow({ taskId, taskTitle, subtasks });

Type guard

function hasActionableSubtasks(subtasks: { id: string; status: string }[]): boolean {
  return subtasks.some((st) => st.status !== 'done');
}

Prevention

When it happens

Trigger: Calling workflowService.startWorkflow({ taskId, subtasks, ... }) where all entries in `subtasks` have status 'done' (already marked completed), so findIndex((st) => st.status !== 'completed') === -1.

Common situations: Re-running start for a task whose subtasks were all finished in a previous run; subtask statuses marked done prematurely (e.g. bulk status update or import marking everything done); passing a filtered subtask list that happens to only contain already-completed items; resuming manually without using resumeWorkflow after all subtasks finished but before FINALIZE ran.

Related errors


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