fix: Handle spawn and branch failures gracefully in dispatch cycle

Wrap agentManager.spawn() in try/catch — on failure, block the task
instead of crashing the entire dispatch cycle. Move phase status update
to after branch creation succeeds — on branch failure, block the phase
and skip task queuing. Fix statement-breakpoint markers in migration
0020 to use separate lines.
This commit is contained in:
Lukas May
2026-03-05 16:36:39 +01:00
parent 42f5bcb80a
commit da8c714de2
4 changed files with 36 additions and 20 deletions

View File

@@ -167,10 +167,7 @@ export class DefaultPhaseDispatchManager implements PhaseDispatchManager {
};
}
// Update phase status to 'in_progress'
await this.phaseRepository.update(nextPhase.phaseId, { status: 'in_progress' });
// Create phase branch in all linked project clones
// Create phase branch in all linked project clones (must succeed before marking in_progress)
if (this.initiativeRepository && this.projectRepository && this.branchManager && this.workspaceRoot) {
try {
const initiative = await this.initiativeRepository.findById(phase.initiativeId);
@@ -204,10 +201,16 @@ export class DefaultPhaseDispatchManager implements PhaseDispatchManager {
log.info({ phaseId: nextPhase.phaseId, phBranch, initBranch }, 'phase branch created');
}
} catch (err) {
log.error({ phaseId: nextPhase.phaseId, err: err instanceof Error ? err.message : String(err) }, 'failed to create phase branch');
const reason = `Branch creation failed: ${err instanceof Error ? err.message : String(err)}`;
log.error({ phaseId: nextPhase.phaseId, err: reason }, 'phase branch creation failed, blocking phase');
await this.blockPhase(nextPhase.phaseId, reason);
return { success: false, phaseId: nextPhase.phaseId, reason };
}
}
// Update phase status to 'in_progress' (only after branches confirmed)
await this.phaseRepository.update(nextPhase.phaseId, { status: 'in_progress' });
// Remove from queue (now being worked on)
this.phaseQueue.delete(nextPhase.phaseId);