claude-code icon indicating copy to clipboard operation
claude-code copied to clipboard

[BUG] Claude Code crashes with OOM when manipulating terminal splits during active generation

Open paskal opened this issue 1 month ago • 3 comments

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?

Claude Code crashes with an Out of Memory (OOM) error when manipulating terminal splits while actively generating output. This causes the entire Ghostty window to close (all tabs and splits lost).

Steps to reproduce:

  1. Open Ghostty
  2. Create 3-4 splits (e.g., 1-2 on left, 1-2 on right)
  3. Run Claude Code in multiple splits (3-4 instances)
  4. Start tasks that cause Claude Code to generate output
  5. While Claude Code is actively working, press Cmd+Enter (zoom split), Cmd+Shift+Enter, or Cmd+D/Cmd+Shift+D (new split)
  6. Result: Entire Ghostty window closes immediately

Crash log analysis:

macOS crash reports (~/Library/Logs/DiagnosticReports/node-*.ips) show V8 JavaScript heap OOM:

"exception": {"type":"EXC_CRASH","signal":"SIGABRT"}
node::OOMErrorHandler -> v8::internal::V8::FatalProcessOutOfMemory -> v8::internal::Heap::CollectGarbage

Key observations:

  • Only happens when Claude Code is actively generating (never when idle)
  • Multiple instances running (3-4 sessions in splits)
  • Multiple crash reports generated simultaneously
  • Not macOS jetsam - this is V8's internal OOM handler calling abort()

Related issues: #16578, #4953, #1555, #1495

What Should Happen?

Terminal split manipulation (zoom, new split) should work without crashing Claude Code, even during active generation. The TUI should handle terminal resize events gracefully without excessive memory allocation.

Error Messages/Logs

"exception": {"type":"EXC_CRASH","signal":"SIGABRT"}
"termination": {"indicator":"Abort trap: 6"}
"asi": {"libsystem_c.dylib":["abort() called"]}

Stack trace:
node::OOMErrorHandler(char const*, v8::OOMDetails const&)
v8::internal::V8::FatalProcessOutOfMemory(...)
v8::internal::Heap::FatalProcessOutOfMemory(...)
v8::internal::Heap::CollectGarbage(...)
v8::internal::HeapAllocator::AllocateRawWithRetryOrFailSlowPath(...)

Full crash reports at: ~/Library/Logs/DiagnosticReports/node-*.ips

Steps to Reproduce

  1. Open Ghostty terminal
  2. Create 3-4 splits (Cmd+D or Cmd+Shift+D) - arrange as 1-2 on left, 1-2 on right
  3. Run claude in multiple splits (3-4 instances simultaneously)
  4. Start tasks in each that cause Claude Code to generate output (e.g., code generation, file editing, tool calls)
  5. While Claude Code is actively working/generating, press one of:
    • Cmd+Enter (zoom/toggle split fullscreen)
    • Cmd+Shift+Enter
    • Cmd+D or Cmd+Shift+D (create new split)
  6. Result: Entire Ghostty window closes immediately - all tabs and splits are lost

Claude Model

Opus

Is this a regression?

Yes, this worked in a previous version

Last Working Version

2.0.76

Claude Code Version

2.1.5 (Claude Code)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Other

Additional Information

Terminal: Ghostty 1.2.3 stable (also reproduced on tip build)

Key observations:

  • Only happens when Claude Code is actively generating output - never when idle
  • Running 3-4 Claude Code instances in terminal splits
  • Split manipulation (zoom, new split) triggers the crash - possibly TUI re-render during resize causes memory spike
  • Multiple crash reports generated simultaneously (3-4 node processes crash together)
  • This is V8's internal OOM handler calling abort(), not macOS jetsam

Crash log location: ~/Library/Logs/DiagnosticReports/node-*.ips

Related issues (for reference):

  • #16578 - Terminal rendering breaks in long conversations
  • #4953 - Memory leak growing to 120+ GB RAM
  • #1555 - Claude Code crashes due to OOM (closed)
  • #1495 - TUI rendering glitching with terminal resizing

paskal avatar Jan 11 '26 23:01 paskal

Found 2 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/17391
  2. https://github.com/anthropics/claude-code/issues/1421

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

github-actions[bot] avatar Jan 11 '26 23:01 github-actions[bot]

Crash Timeline Analysis

I analysed the macOS crash reports and correlated them with Claude Code releases:

Date Time (CET) Event
Jan 7 21:37 v2.0.76 released (confirmed working)
Jan 7 22:31 v2.1.1 released
Jan 9 01:04 v2.1.2 released
Jan 10 00:32 v2.1.3 released
Jan 10 23:56 First OOM crash
Jan 11 01:28 v2.1.4 released
Jan 11 18:05-22:49 21 more crashes (multiple instances crashing together)

Note: I recall updating to v2.1.1 and v2.1.2 without issues. The crashes started after v2.1.3, so v2.1.3 is definitely affected and possibly the first version with this regression.

No node crash reports exist before Jan 10, confirming the issue was introduced in the v2.1.x series.


Full macOS Crash Report

From ~/Library/Logs/DiagnosticReports/node-2026-01-11-180513.ips:

Click to expand full crash log (JSON)
{
  "app_name": "node",
  "timestamp": "2026-01-11 18:05:13.00 +0100",
  "os_version": "macOS 26.2 (25C56)",
  "incident_id": "5C07E998-66A0-4EE1-BC74-F533354589C5",
  "procName": "node",
  "procPath": "/opt/homebrew/*/node",
  "coalitionName": "com.mitchellh.ghostty",
  "cpuType": "ARM-64",
  "modelCode": "Mac15,13",
  
  "exception": {
    "type": "EXC_CRASH",
    "signal": "SIGABRT"
  },
  
  "termination": {
    "code": 6,
    "namespace": "SIGNAL",
    "indicator": "Abort trap: 6"
  },
  
  "asi": {
    "libsystem_c.dylib": ["abort() called"]
  },
  
  "faultingThread": 0,
  "legacyInfo": {
    "threadTriggered": {
      "name": "claude",
      "queue": "com.apple.main-thread"
    }
  }
}

Stack Trace (Thread 0 - "claude")

__pthread_kill
pthread_kill
__abort
abort
node::OOMErrorHandler(char const*, v8::OOMDetails const&)
v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, v8::OOMDetails const&)
v8::internal::Heap::FatalProcessOutOfMemory(char const*)
v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags)
v8::internal::HeapAllocator::AllocateRawWithRetryOrFailSlowPath(...)
v8::internal::FactoryBase<v8::internal::Factory>::NewRawStringWithMap<v8::internal::SeqOneByteString>(...)
v8::internal::Factory::NewStringFromUtf8(...)
v8::String::NewFromUtf8(...)
node::url::BindingData::PathToFileURL(...)
...
node::Environment::CheckImmediate(uv_check_s*)
uv__run_check
uv_run
node::SpinEventLoopInternal(node::Environment*)
node::NodeMainInstance::Run(...)
node::Start(int, char**)

Memory Summary

REGION TYPE                        SIZE    COUNT
===========                     =======  =======
MALLOC                           338.4M       76 
Memory Tag 255                    34.3G    16460   <-- Problem area
Stack                             88.8M       14 
__TEXT                           362.0M      386 
...
TOTAL                             36.1G    18500 

The crash is triggered by V8's OOMErrorHandler when trying to allocate a new UTF-8 string during PathToFileURL. The process was using 36.1GB virtual memory with "Memory Tag 255" consuming 34.3GB across 16,460 regions.

paskal avatar Jan 11 '26 23:01 paskal

Additional findings: Terminal resize triggers the OOM

I did some debugging and found strong evidence that terminal resize events trigger this crash.

Evidence from memory monitoring

Set up a memory monitor logging every 5 seconds while using Claude Code in multiple Ghostty panes. When I resized the terminal window, captured this:

Time PID 63759 PID 64258 PID 66452
01:56:48 502MB 277MB 233MB
01:56:53 968MB 951MB 930MB
01:56:58 1.6GB 1.5GB 1.5GB
01:57:03 1.6GB 1.9GB 1.5GB
01:57:08 2.7GB 2.1GB 2.5GB
01:57:14 2.2GB 2.7GB 2.5GB
01:57:19 485MB 3.1GB 3.0GB

Key observations:

  1. All 3 Claude processes spiked at the exact same moment (01:56:53) - this was when I resized the terminal
  2. Memory jumped 3-4x instantly (277MB → 950MB in <5 seconds)
  3. MCP helper nodes crashed - they disappeared from the process list during the spike
  4. One process recovered via GC (63759 dropped to 485MB), others continued climbing to 3GB+

Multiple crash patterns in stack traces

Analysed crash reports and found the OOM happens during various string operations:

  • CallSitePrototypeToStringArrayPrototypeJoinPrepareStackTraceCallback (stack trace formatting)
  • ErrorPrototypeToString during error handling
  • FastFunctionPrototypeBind in timer callbacks
  • AppendFileLocationSerializeCallSiteInfo (the PathToFileURL pattern from original report)

All crashes share the same memory signature: 34.3GB in "Memory Tag 255" with 16,460+ regions.

Crash clustering pattern

Looking at all crash reports, they always occur in clusters of 2-4 at the exact same time - consistent with a broadcast event (SIGWINCH from terminal resize) affecting all Claude instances simultaneously.

Reproduction

  1. Open multiple Claude Code sessions in a terminal with panes (Ghostty, tmux, etc.)
  2. Let them run for a while with active conversations
  3. Resize the terminal window
  4. Observe memory spike and potential crash

Environment

  • macOS 15.5 (Darwin 25.2.0)
  • Claude Code 2.1.5
  • Ghostty terminal with multiple panes
  • Apple Silicon (M-series)

paskal avatar Jan 13 '26 02:01 paskal

Update: Testing on v2.1.7 reveals a different issue

I've been experiencing similar crashes on v2.1.7 with Ghostty 1.2.3 on macOS (Apple Silicon). After extensive debugging, the behaviour appears different from the original OOM issue described here.

Debugging methodology

Set up monitoring to track:

  • Memory (RSS) every 100ms for all Claude processes
  • Process death events
  • Signal trapping via wrapper scripts
  • Crash report generation

Key findings

1. No memory spike before crash

Unlike the original report showing memory spikes (277MB → 950MB → 34GB), the crashes I observed show stable memory:

20:31:27 PID=55532 RSS=245328KB  (loaded long chat)
20:31:32 PID=55532 RSS=186816KB  (after GC)
20:31:37 PID=55532 RSS=180880KB  (stable)
20:31:37 PID=55532 DIED!

Process dies at normal ~180MB with no spike.

2. No crash reports generated

  • No node crash reports in ~/Library/Logs/DiagnosticReports/
  • No Ghostty crash reports
  • Only orphaned zsh crash (from earlier, unrelated)

3. Signals cannot be caught

Created wrapper scripts with signal traps for SIGHUP, SIGTERM, SIGINT, SIGWINCH, and EXIT. None fired - the process simply vanishes. This indicates either SIGKILL or PTY destruction.

4. Process hierarchy shows PTY destruction

After crash, parent zsh processes have PPID=1 (orphaned), indicating Ghostty terminated/destroyed the PTY surface rather than sending a catchable signal.

Conclusion

What I'm experiencing appears to be Ghostty destroying the PTY when split manipulation occurs, causing the kernel to SIGKILL all attached processes. This is different from the V8 OOM issue in the original report.

Evidence:

  • Memory stable (no spike)
  • No V8 OOM crash signature
  • Uncatchable termination (SIGKILL/PTY destruction)
  • Only affects the specific split being manipulated

Reproduction

  1. Ghostty with splits
  2. Run claude in one split
  3. Load a long conversation via /resume
  4. Expand split (Cmd+Shift+Enter) then unexpand → crash

Recommendation

The original OOM issue may have been addressed in recent versions. The current crash behaviour points to a Ghostty issue with PTY lifecycle management during split operations, not Claude Code memory handling.


Environment:

  • Claude Code: 2.1.7
  • Ghostty: 1.2.3
  • macOS: Darwin 25.2.0 (Apple Silicon)

paskal avatar Jan 15 '26 20:01 paskal

Follow-up: Root cause identified in Ghostty

After further investigation with debug logging, we found the root cause is a Ghostty bug, not Claude Code:

Error: error.HyperlinkMapOutOfMemory during resize when toggling split zoom

Filed: https://github.com/ghostty-org/ghostty/issues/10336

The issue occurs because:

  1. Claude Code outputs many OSC 8 hyperlinks (file paths)
  2. Split zoom toggle causes dramatic terminal resize
  3. Ghostty's HyperlinkMap can't accommodate the resize
  4. Ghostty terminates the PTY/process instead of handling gracefully

This explains why v2.1.7 shows no V8 OOM crashes - the original memory issue may be fixed, but this Ghostty-specific issue causes similar symptoms (process death on split manipulation).

paskal avatar Jan 15 '26 21:01 paskal

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.

github-actions[bot] avatar Jan 23 '26 14:01 github-actions[bot]