eyaltoledano/claude-task-master · error

Cannot finalize workflow in ${phase} phase. Complete all sub

Error message

Cannot finalize workflow in ${phase} phase. Complete all subtasks first.

What it means

Thrown by WorkflowService.finalizeWorkflow() when the workflow orchestrator's current phase is not FINALIZE. Finalization (which commits and wraps up the workflow) is only permitted once all implementation subtasks are complete and the orchestrator has advanced to the FINALIZE phase. Throwing early prevents committing or archiving a half-finished workflow.

Source

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

			await this.updateTaskStatus(completedSubtaskId, 'done', context.tag);
		}

		return this.getStatus();
	}

	/**
	 * Finalize and complete the workflow
	 * Validates working tree is clean before marking complete
	 * Cleans up workflow state file after successful completion
	 */
	async finalizeWorkflow(): Promise<WorkflowStatus> {
		if (!this.orchestrator) {
			throw new Error('No active workflow. Start or resume a workflow first.');
		}

		const phase = this.orchestrator.getCurrentPhase();
		if (phase !== 'FINALIZE') {
			throw new Error(
				`Cannot finalize workflow in ${phase} phase. Complete all subtasks first.`
			);
		}

		// Check working tree is clean
		const gitAdapter = new GitAdapter(this.projectRoot);
		const statusSummary = await gitAdapter.getStatusSummary();

		if (!statusSummary.isClean) {
			throw new Error(
				`Cannot finalize workflow: working tree has uncommitted changes.\n` +
					`Staged: ${statusSummary.staged}, Modified: ${statusSummary.modified}, ` +
					`Deleted: ${statusSummary.deleted}, Untracked: ${statusSummary.untracked}\n` +
					`Please commit all changes before finalizing the workflow.`
			);
		}

		// Capture task ID before transitioning

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Complete all remaining subtasks of the workflow so the orchestrator advances to the FINALIZE phase, then call finalizeWorkflow() again.
  2. Check the current phase first with workflowService.orchestrator.getCurrentPhase() (or an equivalent getter) and only finalize when it equals 'FINALIZE'.
  3. If all subtasks are actually done but the phase is stale, restart or resume the workflow so phase computation re-runs.
  4. If you don't intend to finalize the whole workflow, remove the finalizeWorkflow() call.

Example fix

// before
await workflowService.finalizeWorkflow(); // throws in IMPLEMENT phase
// after
const phase = workflowService.getPhase?.() ?? 'IMPLEMENT';
if (phase === 'FINALIZE') {
  await workflowService.finalizeWorkflow();
} else {
  await workflowService.continueWorkflow(); // finish remaining subtasks first
}
Defensive patterns

Strategy: validation

Validate before calling

// check phase before finalizing
const phase = workflowService.getPhase?.() ?? 'IMPLEMENT';
if (phase !== 'FINALIZE') throw new Error(`Workflow not ready to finalize (phase: ${phase}); complete all subtasks first.`);

Try / catch

try {
  await workflowService.finalizeWorkflow();
} catch (e) {
  if (/Cannot finalize workflow in .* phase/.test(e.message)) {
    // resume/continue workflow until FINALIZE phase
  } else throw e;
}

Prevention

When it happens

Trigger: Calling workflowService.finalizeWorkflow() while the orchestrator's getCurrentPhase() returns IMPLEMENT, REVIEW, or any phase other than 'FINALIZE' — typically because some subtasks are still pending/in-progress.

Common situations: Developers invoking finalize right after starting a workflow, after completing only some subtasks, or resuming a workflow that still has open subtasks. Also occurs when the phase-transition logic hasn't run yet (e.g. subtasks completed but phase not advanced).

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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