fix(handoff): prevent race condition when killing pane processes
Some checks failed
CI / Check for .beads changes (push) Has been skipped
CI / Check embedded formulas (push) Failing after 21s
CI / Test (push) Failing after 1m36s
CI / Coverage Report (push) Has been cancelled
CI / Integration Tests (push) Has been cancelled
CI / Lint (push) Has been cancelled
Windows CI / Windows Build and Unit Tests (push) Has been cancelled

KillPaneProcesses was killing ALL processes in the pane, including the
gt handoff process itself. This created a race condition where the
process could be killed before RespawnPane executes, causing the pane
to close prematurely and requiring manual reattach.

Added KillPaneProcessesExcluding() function that excludes specified PIDs
from being killed. The handoff command now passes its own PID to avoid
the race condition.

Fixes: gt-85qd

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
diesel
2026-01-23 15:39:00 -08:00
committed by John Ogle
parent 1013c36343
commit 03f0b68484
2 changed files with 76 additions and 1 deletions

View File

@@ -206,7 +206,10 @@ func runHandoff(cmd *cobra.Command, args []string) error {
// Kill all processes in the pane before respawning to prevent orphan leaks
// RespawnPane's -k flag only sends SIGHUP which Claude/Node may ignore
if err := t.KillPaneProcesses(pane); err != nil {
// IMPORTANT: Exclude our own process to avoid race condition where we get killed
// before RespawnPane executes, causing the pane to close prematurely (gt-85qd)
myPID := fmt.Sprintf("%d", os.Getpid())
if err := t.KillPaneProcessesExcluding(pane, []string{myPID}); err != nil {
// Non-fatal but log the warning
style.PrintWarning("could not kill pane processes: %v", err)
}