eyaltoledano/claude-task-master · error
Invalid transition: RED_PHASE_COMPLETE from non-RED phase
Error message
Invalid transition: RED_PHASE_COMPLETE from non-RED phase
What it means
TDD sub-phase events are handled by handleTDDPhaseTransition(). RED_PHASE_COMPLETE is only legal when the workflow's currentTDDPhase is 'RED'; dispatching it from GREEN or REFACTOR throws this fixed-message error, since a RED-phase completion implies test results concluding the RED phase.
Source
Thrown at packages/tm-core/src/modules/workflow/orchestrators/workflow-orchestrator.ts:158
`Invalid transition: ${event.type} from ${this.currentPhase}`
);
}
// Execute transition
this.executeTransition(validTransition, event);
await this.triggerAutoPersist();
}
/**
* Handle TDD phase transitions (RED -> GREEN -> COMMIT)
*/
private async handleTDDPhaseTransition(event: WorkflowEvent): Promise<void> {
const currentTDD = this.context.currentTDDPhase || 'RED';
switch (event.type) {
case 'RED_PHASE_COMPLETE':
if (currentTDD !== 'RED') {
throw new Error(
'Invalid transition: RED_PHASE_COMPLETE from non-RED phase'
);
}
// Validate test results are provided
if (!event.testResults) {
throw new Error('Test results required for RED phase transition');
}
// Store test results in context
this.context.lastTestResults = event.testResults;
// Special case: All tests passing in RED phase means feature already implemented
if (event.testResults.failed === 0) {
this.emit('tdd:red:completed');
this.emit('tdd:feature-already-implemented', {
subtaskId: this.getCurrentSubtaskId(),
testResults: event.testResultsView on GitHub (pinned to c0c98d367c)
Solutions
- Check context.currentTDDPhase before dispatching; only send RED_PHASE_COMPLETE from RED.
- If the RED phase already completed, send the next appropriate event (e.g. GREEN/REFACTOR phase events) instead.
- Deduplicate test-runner callbacks so completion fires once.
- When resuming from persisted state, confirm currentTDDPhase was persisted correctly before replaying events.
Example fix
// before
await orchestrator.transition({ type: 'RED_PHASE_COMPLETE', testResults });
// after
if ((orchestrator.context.currentTDDPhase ?? 'RED') === 'RED') {
await orchestrator.transition({ type: 'RED_PHASE_COMPLETE', testResults });
} Defensive patterns
Strategy: validation
Validate before calling
const tdd = orchestrator.context.currentTDDPhase || 'RED';
if (event.type === 'RED_PHASE_COMPLETE' && tdd !== 'RED') {
throw new SkipDispatchError('RED_PHASE_COMPLETE illegal outside RED phase');
} Type guard
function canCompleteRed(ctx, event) {
return event.type !== 'RED_PHASE_COMPLETE'
|| (ctx.currentTDDPhase || 'RED') === 'RED';
} Try / catch
try {
await orchestrator.transition(event);
} catch (e) {
if (e.message.includes('RED_PHASE_COMPLETE from non-RED phase')) {
console.warn('RED already completed; dispatch next phase event instead');
return;
}
throw e;
} Prevention
- Persist currentTDDPhase with workflow state so resumes know the sub-phase
- Fire RED_PHASE_COMPLETE exactly once per RED cycle (dedupe test-runner callbacks)
- Route later-phase events to their own event types, not RED_PHASE_COMPLETE
- Check currentTDDPhase before dispatching TDD events
When it happens
Trigger: Dispatching { type: 'RED_PHASE_COMPLETE' } when context.currentTDDPhase is 'GREEN' or 'REFACTOR' — e.g. double-completing the RED phase, or resuming an orchestrator whose TDD sub-state was already advanced.
Common situations: A test runner callback fires RED_PHASE_COMPLETE twice; restoring state where the RED→GREEN transition already happened; parallel agents each reporting RED completion for the same workflow.
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
- Invalid transition: GREEN_PHASE_COMPLETE from non-GREEN phas
- Invalid transition: COMMIT_COMPLETE from non-COMMIT phase
- Not in active TDD phase
- Cannot commit in ${tddPhase} phase. Complete RED and GREEN p
- Workflow has been aborted
AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29).
Data as JSON: /api/errors/fdd69b4e83202521.
Report an issue: GitHub.