Background Bash runner process (re-exec'd versioned binary) leaks memory after command completes — 100% CPU, OOM-killed at 10.8GB (v2.1.226 & v2.1.233, Linux)
Environment
- Claude Code v2.1.233 (native installer,
~/.local/share/claude/versions/<v>); identical failure previously observed on v2.1.226 - Debian 12 (bookworm) inside an LXC container (Proxmox host), 4 cores, 12 GB RAM, no swap
- Interactive terminal session inside tmux
Summary
The detached runner process that Claude Code spawns to babysit a background Bash task (a re-exec of its own versioned binary — process comm shows as the version number, e.g. 2.1.233, rather than claude) can fail to exit after the command completes. It then spins at 100% CPU allocating memory without bound until the kernel OOM killer removes it. On our 12 GB no-swap host it reached 10.8 GB anon RSS, and the box spent ~15 minutes in direct-reclaim thrash (load ~50, effectively frozen) before the memcg OOM kill fired. This has happened 3 times across two versions (2×2026-08-10 on v2.1.226 at 5.6/5.7 GB, 1×2026-08-17 on v2.1.233 at 10.8 GB).
What happened (2026-08-17 occurrence)
- An interactive session had fanned out 8 parallel background subagents (all in-process — confirmed via the kernel's OOM task dump, which shows only one claude-binary process per interactive session).
- One subagent issued a Bash tool call at 10:56:18 local:
``bash`
cd <data-dir> && grep -oiE '(BlackRock[^<]{0,80}(Income|American)[^<]{0,40})' page.html | sort | uniq -c | sort -rn | head -20
run_in_background` in the recorded tool input, so presumably auto-backgrounded).
The target file is **84 KB**; the pipeline completes in milliseconds with exit 0 and ≤20 lines of output. The call ran as a background task (no explicit
- A separate process appeared (re-exec of
~/.local/share/claude/versions/2.1.233,comm=2.1.233,oom_score_adj: 0, same session cgroup) and ran ~8 minutes at 100% CPU, growing continuously. - Kernel killed it at 11:04:30:
````
Memory cgroup out of memory: Killed process 3766733 (2.1.233) total-vm:12915192kB, anon-rss:10849536kB, file-rss:40kB, shmem-rss:0kB, pgtables:21536kB oom_score_adj:0
- One second later (11:04:31) the parent session's transcript enqueued the task notification:
```
<status>completed</status>
<summary>Background command "Extract fund name mentions from investegate page" completed (exit code 0)</summary>
[exited with code 0]` (22 bytes) — the actual grep output was lost.
The task's output file contains only
- The interactive session and all 8 subagents survived and continued normally.
Prior occurrences (v2.1.226, 2026-08-10)
22:15:31 Killed process 1467427 (2.1.226) total-vm:6596964kB, anon-rss:5576832kB ...
22:38:46 Killed process 1513920 (2.1.226) total-vm:6596964kB, anon-rss:5718912kB ...
Same fingerprint: victim comm is the version number (child re-exec'd via the versioned binary path), spawned from a different interactive session; the sessions themselves (comm claude, 250–470 MB) were unaffected. The identical total-vm on the two kills 23 minutes apart suggests the respawned runner ballooned deterministically a second time.
Expected behavior
The background-task runner should exit promptly when the monitored command completes, and its memory use should be bounded regardless of the command.
Notes
- The command itself is irrelevant/harmless (trivial grep over a small local file, exit 0).
- Because the runner dies with the command's exit code reported as 0 and status "completed", the failure is invisible to the session — the only symptoms are host-level (CPU/memory).
- Happy to provide fuller kernel OOM dumps or transcript excerpts (with paths redacted) on request.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗