fix: orphaned agent processes when deleting a worktree in the TUI - #21
Merged
Conversation
Deleting a worktree and its session from the TUI left the agent's tmux session and the whole process tree under it alive, consuming resources and pointed at a directory that had just been removed. The session stayed invisible to the dashboard, so the only way to notice was to run tmux ls or watch the machine get slower. The delete path killed its two sessions by different mechanisms. The shell session was killed by its tmux session ID, which always works. The agent session went through sesSvc.Stop, which rebuilds the session name from (project, branch) and looks it up in tmux list-sessions. When that lookup missed, Stop returned ErrSessionNotFound, the caller discarded it with `_ =`, and the worktree was force-deleted anyway. The rebuilt name misses for two independent reasons. Stop derives it from Item.Branch, which carries the display branch — a value items.go deliberately lets diverge from the identity branch the session was named after. Stop also hardcodes an empty profile, so under an active profile it searches for myapp-feat while the session is really work-myapp-feat. Both sessions are now killed by the tmux session ID the item already carries, which is immune to both hazards because it never reconstructs a name, and a failed kill surfaces as an error instead of letting the worktree be deleted out from under a live process. This matches what confirmDeleteAgent and confirmDeleteShell already did. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Deleting a worktree and its session from the TUI left the agent's tmux session and the whole process tree under it alive, consuming resources and pointed at a directory that had just been removed. The session stayed invisible to the dashboard, so the only way to notice was to run tmux ls or watch the machine get slower.
The delete path killed its two sessions by different mechanisms. The shell session was killed by its tmux session ID, which always works. The agent session went through sesSvc.Stop, which rebuilds the session name from (project, branch) and looks it up in tmux list-sessions. When that lookup missed, Stop returned ErrSessionNotFound, the caller discarded it with
_ =, and the worktree was force-deleted anyway.The rebuilt name misses for two independent reasons. Stop derives it from Item.Branch, which carries the display branch — a value items.go deliberately lets diverge from the identity branch the session was named after. Stop also hardcodes an empty profile, so under an active profile it searches for myapp-feat while the session is really work-myapp-feat.
Both sessions are now killed by the tmux session ID the item already carries, which is immune to both hazards because it never reconstructs a name, and a failed kill surfaces as an error instead of letting the worktree be deleted out from under a live process. This matches what confirmDeleteAgent and confirmDeleteShell already did.