Summary
Opening a URL/browser leaves a permanent zombie (<defunct>) child process. A long-running session was observed with 5 zombie children parented to the docker-agent process.
Root cause
pkg/browser/browser.go calls exec.CommandContext(...).Start() but never calls Wait(), so the child is never reaped after it exits and remains a zombie.
Triggers
Every browser/URL open path, including MCP OAuth handshakes, TUI open-link, and the open_url tool. Five zombies correlated with five browser opens.
Proposed fix
Reap the child asynchronously, following the existing pattern in pkg/board/app.go:
go func() { _ = cmd.Wait() }()
Impact
Accumulating zombies consume PIDs and indicate missing process lifecycle management; over long sessions this can contribute to process-table pressure.
Summary
Opening a URL/browser leaves a permanent zombie (
<defunct>) child process. A long-running session was observed with 5 zombie children parented to thedocker-agentprocess.Root cause
pkg/browser/browser.gocallsexec.CommandContext(...).Start()but never callsWait(), so the child is never reaped after it exits and remains a zombie.Triggers
Every browser/URL open path, including MCP OAuth handshakes, TUI open-link, and the
open_urltool. Five zombies correlated with five browser opens.Proposed fix
Reap the child asynchronously, following the existing pattern in
pkg/board/app.go:Impact
Accumulating zombies consume PIDs and indicate missing process lifecycle management; over long sessions this can contribute to process-table pressure.