eyaltoledano/claude-task-master · error

Guard condition failed

Error message

Guard condition failed

What it means

The orchestrator's phase-specific guard for the transition's target phase returned false. Unlike the transition's own guard (error 255), this guard is looked up in the `phaseGuards` map by target phase name, so any transition into that phase is blocked until the WorkflowContext satisfies the registered condition. It throws a generic message and does not name the failing phase, which makes it harder to diagnose.

Source

Thrown at packages/tm-core/src/modules/workflow/orchestrators/workflow-orchestrator.ts:310

	/**
	 * Execute a state transition
	 */
	private executeTransition(
		transition: StateTransition,
		event: WorkflowEvent
	): void {
		// Check guard condition if present
		if (transition.guard && !transition.guard(this.context)) {
			throw new Error(
				`Guard condition failed for transition to ${transition.to}`
			);
		}

		// Check phase-specific guard if present
		const phaseGuard = this.phaseGuards.get(transition.to);
		if (phaseGuard && !phaseGuard(this.context)) {
			throw new Error('Guard condition failed');
		}

		// Emit phase exit event
		this.emit('phase:exited');

		// Update context based on event
		this.updateContext(event);

		// Transition to new phase
		this.currentPhase = transition.to;

		// Emit phase entry event
		this.emit('phase:entered');

		// Initialize TDD phase if entering SUBTASK_LOOP
		if (this.currentPhase === 'SUBTASK_LOOP') {
			this.context.currentTDDPhase = 'RED';
			this.emit('tdd:red:started');

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Find the phaseGuard registered for `transition.to` (search registerPhaseGuard calls) and log/evaluate it manually against the current context to see which condition fails.
  2. Fix the WorkflowContext so the phase guard's condition passes before transitioning (e.g. correct currentSubtaskIndex, subtask statuses, or branchName).
  3. Remove or relax the overly strict phase guard if it no longer matches your workflow semantics.
  4. If state is corrupted, delete the workflow state file and restart with startWorkflow() instead of resumeWorkflow().

Example fix

// before
orchestrator.registerPhaseGuard('SUBTASK_LOOP', (ctx) => ctx.currentSubtaskIndex === 0);
await orchestrator.transition({ type: 'BRANCH_CREATED', branchName }); // resumed at index 2 -> throws
// after
orchestrator.registerPhaseGuard('SUBTASK_LOOP', (ctx) => ctx.currentSubtaskIndex < ctx.subtasks.length);
await orchestrator.transition({ type: 'BRANCH_CREATED', branchName });
Defensive patterns

Strategy: try-catch

Validate before calling

const ctx = orchestrator.getContext();
const targetPhase = resolveTargetPhase(event.type); // phase the transition leads to
// Re-evaluate the registered phase guard yourself for a precise diagnostic
// (guardMap is internal, so keep your own mirror of guards you register)
for (const [phase, guard] of Object.entries(myRegisteredGuards)) {
  if (phase === targetPhase && !guard(ctx)) {
    throw new Error(`Phase guard for ${phase} would fail with current context`);
  }
}

Try / catch

try {
  await orchestrator.transition(event);
} catch (err) {
  if (err instanceof Error && err.message === 'Guard condition failed') {
    // Generic message: the failing check is the PHASE guard for transition.to
    console.error(`Phase guard rejected transition into target phase for event ${event.type}. Inspect phaseGuards and context.`);
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling orchestrator.transition(event) whose resolved StateTransition.to has a guard registered via registerPhaseGuard(to, guard), and `phaseGuard(this.context)` returns false. Same flow as error 255 but the failing check comes from the phaseGuards map, e.g. transitioning into a phase that requires subtasks to be pending or a branch to exist.

Common situations: Custom phase guards registered for a phase that assume context state from a different workflow configuration; corrupted/edited persisted state resumed into the orchestrator; event emitted twice so context already advanced past what the guard expects; test code registering strict phase guards then replaying transitions.

Related errors


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