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
- Find the phaseGuard registered for `transition.to` (search registerPhaseGuard calls) and log/evaluate it manually against the current context to see which condition fails.
- Fix the WorkflowContext so the phase guard's condition passes before transitioning (e.g. correct currentSubtaskIndex, subtask statuses, or branchName).
- Remove or relax the overly strict phase guard if it no longer matches your workflow semantics.
- 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
- Keep a named registry of phase guards you register so failures can be traced to a phase quickly.
- Write phase guards that tolerate resumed contexts (e.g. currentSubtaskIndex > 0).
- Unit-test every phase guard against fresh, mid-progress, and resumed contexts.
- Don't register guards for phases you don't transition into.
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
- Guard condition failed for transition to ${transition.to}
- Workflow has been aborted
- Invalid transition: ${event.type} from ${this.currentPhase}
- Invalid transition: RED_PHASE_COMPLETE from non-RED phase
- Invalid transition: GREEN_PHASE_COMPLETE from non-GREEN phas
AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29).
Data as JSON: /api/errors/ae24ab7b0eee7cbd.
Report an issue: GitHub.