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
- Call resumeWorkflow() (or the `resume` command) to continue the existing workflow instead of starting over.
- Pass force: true in StartWorkflowOptions to discard the existing state and start fresh.
- Manually remove the persisted workflow state file (in the project's workflow state directory) if it is stale and you do not need it.
- 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
- Always check hasWorkflow()/getStatus() before calling startWorkflow.
- Never commit or sync the workflow state directory between machines or branches.
- Finish or explicitly force-reset workflows before starting new ones on the same repo.
- Add force: true only after confirming the existing state is stale.
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
- branch already exists: ${branchName}
- Workflow state file not found at ${this.statePath}
- Failed to load workflow state: ${error.message}
- Failed to generate valid JSON from workflow state
- Failed to save workflow state: ${error.message}
AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29).
Data as JSON: /api/errors/456b0781d4fcc59a.
Report an issue: GitHub.