eyaltoledano/claude-task-master · error

Workflow already exists. Use force=true to override or resum

Error message

Workflow already exists. Use force=true to override or resume existing workflow.

What it means

startWorkflow() refuses to create a new TDD workflow when a workflow state file already exists for the project and the caller did not pass force=true. The state file represents a live or interrupted workflow; silently overwriting it could lose progress. The error tells you to either override with force or resume the existing workflow instead.

Source

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

	}

	/**
	 * Start a new TDD workflow
	 */
	async startWorkflow(options: StartWorkflowOptions): Promise<WorkflowStatus> {
		const {
			taskId,
			taskTitle,
			subtasks,
			maxAttempts = 3,
			force,
			tag,
			orgSlug
		} = options;

		// Check for existing workflow
		if ((await this.hasWorkflow()) && !force) {
			throw new Error(
				'Workflow already exists. Use force=true to override or resume existing workflow.'
			);
		}

		// Initialize git adapter and ensure clean state
		const gitAdapter = new GitAdapter(this.projectRoot);
		await gitAdapter.ensureGitRepository();
		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
		}));

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Call resumeWorkflow() (or the `resume` command) to continue the existing workflow instead of starting over.
  2. Pass force: true in StartWorkflowOptions to discard the existing state and start fresh.
  3. Manually remove the persisted workflow state file (in the project's workflow state directory) if it is stale and you do not need it.
  4. Check getStatus()/hasWorkflow() before calling startWorkflow to decide programmatically between resume and force.

Example fix

// before
await workflowService.startWorkflow({ taskId: '1', taskTitle: 'X', subtasks });
// after
if (await workflowService.hasWorkflow()) {
  await workflowService.resumeWorkflow();
} else {
  await workflowService.startWorkflow({ taskId: '1', taskTitle: 'X', subtasks });
}
// or intentionally override:
await workflowService.startWorkflow({ taskId: '1', taskTitle: 'X', subtasks, force: true });
Defensive patterns

Strategy: validation

Validate before calling

if (await workflowService.hasWorkflow()) {
  // decide: resume or force
  await workflowService.resumeWorkflow(); // or startWorkflow({...,force:true})
} else {
  await workflowService.startWorkflow(options);
}

Try / catch

try {
  await workflowService.startWorkflow(options);
} catch (err) {
  if (err instanceof Error && err.message.includes('Workflow already exists')) {
    await workflowService.resumeWorkflow(); // continue existing work
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: Calling workflowService.startWorkflow(options) (or the `start` CLI/MCP command) when stateManager.exists() returns true (a previous workflow was started and its state file persists in .taskmaster/workflow or equivalent) and options.force is not true.

Common situations: Re-running `taskmaster start` after a previous run crashed without cleanup; switching branches or pulling changes without finishing the prior workflow; running start from a repo where a teammate's or CI's state file was committed; forgetting that a workflow was already started on the same task days earlier.

Related errors


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