[BUG] Worktree session hangs indefinitely after answering keep/remove prompt (native Linux)

Resolved 💬 1 comment Opened Jun 8, 2026 by NodeJSmith Closed Jul 15, 2026

Environment

  • Claude Code: 2.1.168
  • OS: Ubuntu 24.04.4 LTS (native Linux, not WSL2)
  • Kernel: 6.8.0-124-generic x86_64
  • Hardware: Hetzner cloud VM, AMD EPYC-Rome, 15GB RAM
  • Shell: zsh
  • tmux: 3.6b (but issue reproduces both inside and outside tmux)
  • MCP servers configured: serena, ha-mcp, browser-feedback (Playwright)

Bug Description

After exiting an interactive worktree session (claude -w <name>), Claude Code shows the "Keep or remove worktree?" prompt. After answering (either keep or remove), the process hangs indefinitely with a spinner. It never exits on its own. The only recovery is Ctrl-C or killing the process.

This happens every time on this machine. It does not happen on three other machines (all WSL2) running the same Claude Code version with the same configuration. This machine is the only native Linux box.

Reproduction

  1. cd into any git repo
  2. claude -w test (or any worktree name)
  3. Do anything (or nothing) in the session
  4. /exit
  5. Answer the "Keep or remove worktree?" prompt (either choice)
  6. Process hangs with spinner indefinitely

Verified variants that all hang:

  • Both "keep" and "remove" answers
  • With and without tmux
  • With a shell wrapper and with command claude directly
  • Across multiple repos

strace Analysis

Attached strace to the hung process (PID 1986808, claude -w test in a worktree on pts/2).

What the process IS doing

Rendering spinner animation to the terminal:

write(13, "\33[H\r\33[32B\33[38;5;231m*\33[39m\33[34;1H", 33)
write(13, "\33[H\r\33[32B\33[38;5;231m\342\234\242\33[39m\33[34;1H", 35)
write(13, "\33[H\r\33[32B\33[38;5;231m\302\267\33[39m\33[34;1H", 34)

V8 worker threads in tight futex wake/wait cycles (idle event loop, no pending work).

One thread blocked on inotify read (fd 17), watching:

  • ~/.claude/settings.json
  • <worktree>/.claude/ directory
  • ~/.claude/ directory

What the process is NOT doing

  • No stdin reads (not waiting for user input)
  • No network I/O (TCP connection to Anthropic API is ESTABLISHED but idle)
  • No hook invocations (no child process spawning, no execve calls)
  • No git operations
  • No MCP communication (unix sockets to MCP servers open but idle)

MCP servers still alive as children

claude(1986808)---MainThread(1986875)  # browser-feedback
                |-ha-mcp(1986883)
                |-serena(1986869)---sh---python---MainThread
                +-{claude threads}

All three MCP servers are sleeping (state S). They appear to have never received a shutdown signal. The Claude process is not sending anything to their unix sockets.

Key observation

The process appears stuck in an internal async operation (a Promise that never resolves). The Node.js event loop is alive but has no pending I/O, timers, or subprocess waits to drive it forward. The spinner keeps rendering, but the exit/cleanup flow never progresses past the worktree prompt.

What we ruled out

| Hypothesis | Evidence | Verdict |
|---|---|---|
| git worktree remove is slow | Timed: 56ms create, 164ms remove | Eliminated |
| Hooks hanging during exit | strace shows zero hook invocations | Eliminated |
| Network/API timeout | TCP connection established but zero I/O | Eliminated |
| Waiting for stdin | No read(0, ...) calls | Eliminated |
| File locks in .git/worktrees/ | No lock files present | Eliminated |
| tmux interaction | Reproduces outside tmux | Eliminated |
| Shell wrapper issue | Reproduces with command claude | Eliminated |
| MCP server blocking shutdown | MCP servers idle; Claude never attempts shutdown | Partial |

Possibly related issues

  • #63591 -- worktree parent process doesn't exit (different: parent shell, not the session itself)
  • #59390 -- --print mode hangs post-completion (different: --print mode, macOS)
  • #1935 -- orphaned MCP servers after exit (different: post-exit, not during)

Machine-specific factor

The distinguishing factor is native Linux (Hetzner VM). All three machines where exit works are WSL2 (Windows + WSL2 kernel 6.6.x). Same Claude Code version, same configuration, same MCP servers. Could be a signal handling or event loop difference between native Linux and WSL2.

View original on GitHub ↗

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