[BUG] CLI enters infinite CPU loop when agent deletes .claude/commands/ with duplicate slash commands from nested directories

Resolved 💬 5 comments Opened Feb 22, 2026 by alexeyv Closed Mar 25, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

When slash commands exist in both a parent directory's .claude/commands/ and a child project's .claude/commands/ (identical commands at both levels), the CLI shows duplicated commands with broken scrolling behavior. When the agent autonomously decides to fix this by running rm -r .claude/commands/ on the inner directory, the CLI enters an infinite CPU-burning loop and becomes completely unresponsive.

The process consumed 33% CPU sustained for 13+ hours before being killed externally with SIGTERM. It was unresponsive to Ctrl-C and Ctrl-Z from the terminal — only an external kill -TERM worked.

Key detail: the deletion was agent-initiated, not user-initiated. The user told Claude about the duplicate commands; Claude decided rm -r .claude/commands/ was the fix and executed it via the Bash tool. The Bash tool completed successfully (directory was deleted), but the tool result was never delivered back to the agent loop, leaving it in an infinite processing state.

What Should Happen?

  1. Duplicate slash commands from nested .claude/ directories should be deduplicated gracefully
  2. Deleting a .claude/commands/ directory (whether by user or agent) should not freeze the process
  3. At minimum, Ctrl-C should always work to interrupt the process

Steps to Reproduce

  1. Have a parent directory with .claude/commands/ containing N slash commands
  2. Install the same slash commands into a child project's .claude/commands/
  3. Launch Claude CLI in the child directory — observe duplicate commands in the slash command list with broken scrolling behavior in the TUI
  4. Tell Claude to fix the duplication — it will naturally choose to rm -r the inner .claude/commands/
  5. Process enters infinite CPU loop, unresponsive to terminal signals

Diagnostic Data

Process state at time of investigation (13h after freeze):

  • PID state: R+ (running, foreground)
  • CPU: 33.8% sustained, 251+ minutes total CPU time
  • Memory: 567 MB physical
  • No child processes
  • Session file still being touched but no new meaningful entries

Stack analysis (via macOS sample tool):

  • Main thread: ~71% of samples in kevent64 (event loop), ~29% in deep JS execution stacks
  • All 11 Bun worker pool threads sleeping on __psynch_cvwait
  • All 11 nucleo I/O threads sleeping on __psynch_cvwait
  • JIT compiler threads intermittently active (still compiling after 13h)
  • Binary is stripped so function names show as offsets, but Anthropic can symbolicate against debug symbols for v2.1.50

Session log shows: The Bash tool call (rm -r .claude/commands/) completed — the directory was actually deleted — but the tool result was never processed by the agent. The last entries are the Bash progress/result followed by what appears to be a file watcher or hook event that never resolves.

CPU sample files (1s and 2s samples taken ~10s apart, showing stable loop pattern) are attached.

Error Messages/Logs

No error messages — the process silently spins with no output. The TUI showed "Running..." on the Bash tool and a thinking indicator that never resolved.

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.50

Platform

Anthropic API

Operating System

macOS 26.3 (Darwin 25.3.0), ARM64

Terminal/Shell

bash

Additional Context

  • The CLI is built on Bun (not Node.js), confirmed by thread names in CPU samples
  • The process was launched with --dangerously-skip-permissions --plugin-dir pan-out
  • A team (wip-execution) was active in the session
  • Session ID: 68223e32-ebfd-43be-94ec-498907121519
  • The file watcher thread was active in the process, suggesting it may have reacted to the .claude/commands/ deletion and triggered the infinite loop

Hypothesis: The file watcher detects the deletion of .claude/commands/, triggers a slash command re-resolution, which interacts badly with the pending Bash tool result delivery, creating a deadlock or infinite retry loop in the event loop.

View original on GitHub ↗

This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗