{"record":{"id":"0aa5d6497c27c2f6","repo":"eyaltoledano/claude-task-master","slug":"all-subtasks-for-task-taskid-are-already-comple","errorCode":null,"errorMessage":"All subtasks for task ${taskId} are already completed. Nothing to do.","messagePattern":"All subtasks for task (.+?) are already completed\\. Nothing to do\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/tm-core/src/modules/workflow/services/workflow.service.ts","lineNumber":197,"sourceCode":"\t\tawait gitAdapter.ensureCleanWorkingTree();\n\n\t\t// Parse subtasks to WorkflowContext format\n\t\tconst workflowSubtasks: SubtaskInfo[] = subtasks.map((st) => ({\n\t\t\tid: st.id,\n\t\t\ttitle: st.title,\n\t\t\tstatus: st.status === 'done' ? 'completed' : 'pending',\n\t\t\tattempts: 0,\n\t\t\tmaxAttempts: st.maxAttempts || maxAttempts\n\t\t}));\n\n\t\t// Find the first incomplete subtask to resume from\n\t\tconst firstIncompleteIndex = workflowSubtasks.findIndex(\n\t\t\t(st) => st.status !== 'completed'\n\t\t);\n\n\t\t// If all subtasks are already completed, throw an error\n\t\tif (firstIncompleteIndex === -1) {\n\t\t\tthrow new Error(\n\t\t\t\t`All subtasks for task ${taskId} are already completed. Nothing to do.`\n\t\t\t);\n\t\t}\n\n\t\t// Create workflow context, starting from first incomplete subtask\n\t\tconst context: WorkflowContext = {\n\t\t\ttaskId,\n\t\t\tsubtasks: workflowSubtasks,\n\t\t\tcurrentSubtaskIndex: firstIncompleteIndex,\n\t\t\ttag,\n\t\t\terrors: [],\n\t\t\tmetadata: {\n\t\t\t\tstartedAt: new Date().toISOString(),\n\t\t\t\ttaskTitle,\n\t\t\t\tresumedFromSubtask:\n\t\t\t\t\tfirstIncompleteIndex > 0\n\t\t\t\t\t\t? workflowSubtasks[firstIncompleteIndex].id\n\t\t\t\t\t\t: undefined","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/packages/tm-core/src/modules/workflow/services/workflow.service.ts#L179-L215","documentation":"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.","triggerScenarios":"Calling workflowService.startWorkflow({ taskId, subtasks, ... }) where all entries in `subtasks` have status 'done' (already marked completed), so findIndex((st) => st.status !== 'completed') === -1.","commonSituations":"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.","solutions":["Verify the task's subtask statuses; if truly done, no workflow is needed — mark the main task done instead of starting a workflow.","If statuses are wrong, reset the relevant subtasks to 'pending' before calling startWorkflow.","Pass the full unfiltered subtask list; ensure you are not accidentally passing only completed subtasks.","If a workflow already tracked this task, use resumeWorkflow() to reach the FINALIZE phase rather than calling startWorkflow again."],"exampleFix":"// before\nconst subtasks = task.subtasks; // all marked 'done'\nawait workflowService.startWorkflow({ taskId, taskTitle, subtasks });\n// after\nconst actionable = task.subtasks.filter((st) => st.status !== 'done');\nif (actionable.length === 0) {\n  await taskService.setTaskStatus(taskId, 'done'); // nothing to do\n} else {\n  await workflowService.startWorkflow({ taskId, taskTitle, subtasks: task.subtasks });\n}","handlingStrategy":"validation","validationCode":"const pending = subtasks.filter((st) => st.status !== 'done');\nif (pending.length === 0) {\n  // nothing to do: mark task done or bail out early\n  return; // or await taskService.setTaskStatus(taskId, 'done');\n}\nawait workflowService.startWorkflow({ taskId, taskTitle, subtasks });","typeGuard":"function hasActionableSubtasks(subtasks: { id: string; status: string }[]): boolean {\n  return subtasks.some((st) => st.status !== 'done');\n}","tryCatchPattern":null,"preventionTips":["Pre-check subtask statuses before invoking startWorkflow.","Avoid bulk status updates that mark all subtasks done accidentally.","Pass the complete subtask list, not a filtered subset that may exclude pending items.","Use resumeWorkflow() when a workflow already drove the task toward completion."],"tags":["workflow","subtasks","no-op","validation"],"backgroundTag":"workflow-nothing-to-do","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}