Long-running session exhausts macOS kernel file table (ENFILE) and locks the host

Resolved 💬 3 comments Opened May 12, 2026 by chasing-pointers Closed May 16, 2026

Summary

A long-running Claude Code session on macOS exhausted the system-wide
file descriptor table (kern.maxfiles, ENFILE — "too many open files in
system", not the per-process limit), rendering the entire Mac unusable
and requiring a hard power cycle to recover. Every other process began
failing simultaneously (btop, zsh powerlevel10k tmp writes, gcloud
auth helpers, etc.). This is the second occurrence in a few days on
the same machine.

Recovery cost was non-trivial: lost ~100 browser tabs, had to
re-auth Docker / gcloud / GitHub / every other tool, lost the
in-flight session.

Environment

  • Claude Code CLI (bun-bundled — stack frames in

$bunfs/root/src/entrypoints/cli.js)

  • macOS, Darwin 25.4.0
  • Mac Studio, 256 GB unified memory; memory usage at crash was ~20% of

total. Not a memory pressure event.

  • Session was an engineering workflow run with several background

subagents over its lifetime.

What I saw

Pane 1 (Claude Code crashing):

ERROR ENFILE: file table overflow, stat '/Users/randolph/.claude/.claude.json'
at statSync (unknown)
at <several frames> ($bunfs/root/src/entrypoints/cli.js:56:829)
($bunfs/root/src/entrypoints/cli.js:143:1055)
...

Pane 2 (fresh zsh, same instant):

zsh: too many open files in system: btopbtop
_p9k_dump_instant_prompt:sysopen:388: can't open file ~/.cache/p10k-randolph/prompt-33.tmp.6539: too many open files in system
_p9k_dump_state:sysopen:6: can't open file ~/.cache/p10k-dump-randolph.zsh.tmp.6539: too many open files in system

"too many open files in system" = kernel-wide ENFILE, not the
per-process EMFILE. Once that triggers, Activity Monitor / Console /
lsof can't launch either — only the hardware power button works.

Hypothesis

The statSync('/Users/randolph/.claude/.claude.json') from the CLI
entrypoint is the call that finally tipped it over, not the source of
the leak. The underlying cause is fds being held open (or
created-without-closing) across a long session — likely some
combination of file watchers, background subagent / Monitor pipes that
outlive their parent, or stat-loop on .claude.json.

Asks

  1. Bound the fd count for background subagent / Monitor lifetimes so a

long session can't drain the kernel table.

  1. Sample the runtime's own fd count and warn the user before it

approaches the host limit, with a path to gracefully checkpoint.

  1. Catch ENFILE on the .claude.json stat path and bail with state

preserved instead of crashing the runtime.

Happy to attach lsof / sysctl kern.maxfiles output if there's a
way to capture it before the host locks up.

View original on GitHub ↗

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