Agent teams: tmux socket unlinked while server alive — ghost servers and leaked tmux-spawn scopes

Resolved 💬 1 comment Opened Apr 29, 2026 by magnum6actual Closed May 31, 2026

Summary

Agent teams tmux management unlinks the socket file at /tmp/tmux-<uid>/default while the tmux server process is still running. This creates unreachable "ghost" tmux servers and leaks tmux-spawn-*.scope systemd transient units. The user's interactive tmux is also broken because agent teams share the default socket.

Environment

  • Claude Code: Opus 4.6 via CLI
  • OS: Linux 6.17.0-1011-azure (Ubuntu)
  • tmux: default system package
  • Platform: Linux headless server (SSH)

Symptoms

$ tmux ls
error connecting to /tmp/tmux-1000/default (No such file or directory)

This is not the normal "no server running" message — it means the socket file was deleted while tmux still expected to find one.

Investigation findings

Two ghost tmux servers running unreachable

Both were tmux new-session -d -s squad-goals processes, still alive but unreachable via any tmux client:

| PID | Started (UTC) | Uptime at discovery | RSS |
|---|---|---|---|
| 17000 | 2026-04-28 06:21 | 1d 7h 54m | 14.8 MB |
| 1115212 | 2026-04-28 23:26 | 14h 49m | 21.1 MB |

lsof showed both bound to /tmp/tmux-1000/default with different socket inodes (70641 and 4242690). The path had been unlinked from the filesystem — both servers were listening into the void.

80 leaked tmux-spawn-* systemd scopes

The user's systemd manager had 80 tmux-spawn-*.scope transient units in active (running) state, all parented to the two ghost server PIDs.

  • 77 of 80 scopes had zero processes inside — their pane processes had exited but the transient scopes don't self-deactivate when empty
  • 3 scopes still contained idle -bash shells detached from any client

These consumed 80 systemd unit slots, 80 cgroup directories, and associated file descriptors — all leaked.

Likely sequence

  1. Agent team spawns tmux server A, binds socket at /tmp/tmux-1000/default
  2. Team teardown (or a new team spawn) unlinks the socket file while server A is still running
  3. Next agent team spawn can't find a server (no socket), starts server B, creates a new socket
  4. That socket is also unlinked during teardown
  5. Both servers are now ghosts — alive but unreachable
  6. The user's interactive tmux ls sees neither server

User's interactive tmux is collateral damage

Agent teams use the shared default tmux socket (/tmp/tmux-1000/default). Any socket disruption during team lifecycle breaks the user's interactive tmux sessions too. This is a significant footgun — team operations should not affect user tmux state.

Root cause

Something in the agent teams tmux teardown path removes the socket file at /tmp/tmux-1000/default rather than using tmux kill-session or tmux kill-server. Removing the socket file does not kill the server — it just hides it from all clients, creating a ghost.

Additionally, tmux-spawn-*.scope transient units are never explicitly stopped during teardown. Since systemd transient scopes don't auto-deactivate when their last process exits, they accumulate indefinitely.

Suggested fixes

  1. Never rm/unlink files under /tmp/tmux-*/ — the tmux server owns its socket file lifecycle. Use tmux kill-session -t <name> or tmux kill-server for teardown.
  1. Isolate team sockets from user sessions — use tmux -L <team-id> (named socket) instead of the default socket. This way team lifecycle cannot break the user's interactive tmux.
  1. Reap tmux-spawn-* scopes on teardown — after killing a team session, explicitly systemctl --user stop any tmux-spawn-*.scope units that belonged to that team's server PID.
  1. Postcondition check — after team teardown, verify that no tmux processes from the team are still alive and no orphaned scopes remain.

Related

  • #41877 — similar ghost-server outcome but different trigger (cgroup race crash vs. socket unlink)

Cleanup that was required

kill 17000 1115212                          # SIGTERM both ghost servers
systemctl --user stop tmux-spawn-*.scope    # reap 77 empty scopes
rm /tmp/tmux-1000/default                   # remove orphaned socket

After cleanup: 0 ghost processes, 0 leaked scopes, tmux ls returns normal "no server running" message.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗