FATAL ERROR: JavaScript heap out of memory when parsing large .claude.json state file

Resolved 💬 3 comments Opened Oct 29, 2025 by maxajbarlow Closed Nov 2, 2025

Description

Claude Code crashed with a JavaScript heap out of memory error after running for approximately 47 hours. The crash occurred during JSON parsing of the .claude.json state file.

Environment

  • Claude Code Version: 2.0.14
  • Node.js Version: v23.11.0
  • npm Version: 10.9.2
  • OS: macOS Darwin 25.0.0 (arm64)
  • Working Directory: Home directory (76GB total)

Root Cause

The .claude.json state file grew to 8.4MB (3,475 lines), which caused Node.js to run out of heap memory during JSON parsing.

-rw-r--r--@ 1 maxbarlow  staff   8.4M 29 Oct 19:51 .claude.json
-rw-r--r--@ 1 maxbarlow  staff   8.4M 29 Oct 19:51 .claude.json.backup

Stack Trace

<--- Last few GCs --->

[73208:0x8ab40c000] 168954279 ms: Mark-Compact 2007.4 (2076.5) -> 1978.0 (2050.4) MB, pooled: 13 MB, 275.08 / 0.00 ms  (average mu = 0.191, current mu = 0.248) allocation failure; scavenge might not succeed
[73208:0x8ab40c000] 168954675 ms: Mark-Compact 1994.7 (2067.1) -> 1994.7 (2067.1) MB, pooled: 13 MB, 383.33 / 0.00 ms  (average mu = 0.112, current mu = 0.033) allocation failure; scavenge might not succeed


<--- JS stacktrace --->

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
----- Native stack trace -----

 1: 0x105199f0c node::OOMErrorHandler(char const*, v8::OOMDetails const&) [/opt/homebrew/Cellar/node/23.11.0/bin/node]
 2: 0x105345ca4 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, v8::OOMDetails const&) [/opt/homebrew/Cellar/node/23.11.0/bin/node]
 3: 0x105502ce8 v8::internal::Heap::CallGCPrologueCallbacks(v8::GCType, v8::GCCallbackFlags, v8::internal::GCTracer::Scope::ScopeId) [/opt/homebrew/Cellar/node/23.11.0/bin/node]
 4: 0x105508780 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags)::$_1::operator()() const [/opt/homebrew/Cellar/node/23.11.0/bin/node]
 5: 0x10550302c void heap::base::Stack::SetMarkerAndCallbackImpl<v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags)::$_1>(heap::base::Stack*, void*, void const*) [/opt/homebrew/Cellar/node/23.11.0/bin/node]
 6: 0x1050ac028 PushAllRegistersAndIterateStack [/opt/homebrew/Cellar/node/23.11.0/bin/node]
 7: 0x1054fff14 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/opt/homebrew/Cellar/node/23.11.0/bin/node]
 8: 0x1054f9968 v8::internal::HeapAllocator::AllocateRawWithLightRetrySlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/opt/homebrew/Cellar/node/23.11.0/bin/node]
 9: 0x1054fa330 v8::internal::HeapAllocator::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/opt/homebrew/Cellar/node/23.11.0/bin/node]
10: 0x1054e6540 v8::internal::MaybeHandle<v8::internal::SeqOneByteString> v8::internal::FactoryBase<v8::internal::Factory>::NewRawStringWithMap<v8::internal::SeqOneByteString>(int, v8::internal::Tagged<v8::internal::Map>, v8::internal::AllocationType) [/opt/homebrew/Cellar/node/23.11.0/bin/node]
11: 0x1055cd00c v8::internal::JsonParser<unsigned short>::MakeString(v8::internal::JsonString const&, v8::internal::Handle<v8::internal::String>) [/opt/homebrew/Cellar/node/23.11.0/bin/node]
12: 0x1055cd5a8 v8::internal::JsonParser<unsigned short>::ParseJsonObject(v8::internal::Handle<v8::internal::Map>) [/opt/homebrew/Cellar/node/23.11.0/bin/node]
13: 0x1055cd5b8 v8::internal::JsonParser<unsigned short>::ParseJsonObject(v8::internal::Handle<v8::internal::Map>) [/opt/homebrew/Cellar/node/23.11.0/bin/node]
14: 0x1055cd5b8 v8::internal::JsonParser<unsigned short>::ParseJsonObject(v8::internal::Handle<v8::internal::Map>) [/opt/homebrew/Cellar/node/23.11.0/bin/node]
15: 0x1055cdaf8 v8::internal::JsonParser<unsigned short>::ParseJsonArray() [/opt/homebrew/Cellar/node/23.11.0/bin/node]
16: 0x1055cd578 v8::internal::JsonParser<unsigned short>::ParseJsonObject(v8::internal::Handle<v8::internal::Map>) [/opt/homebrew/Cellar/node/23.11.0/bin/node]
17: 0x1055cd5b8 v8::internal::JsonParser<unsigned short>::ParseJsonObject(v8::internal::Handle<v8::internal::Map>) [/opt/homebrew/Cellar/node/23.11.0/bin/node]
18: 0x1055cd5b8 v8::internal::JsonParser<unsigned short>::ParseJsonObject(v8::internal::Handle<v8::internal::Map>) [/opt/homebrew/Cellar/node/23.11.0/bin/node]
19: 0x1055cbff8 v8::internal::JsonParser<unsigned short>::Parse(v8::internal::Isolate*, v8::internal::Handle<v8::internal::String>, v8::internal::Handle<v8::internal::Object>) [/opt/homebrew/Cellar/node/23.11.0/bin/node]
20: 0x1053b5d68 v8::internal::Builtin_JsonParse(int, unsigned long*, v8::internal::Isolate*) [/opt/homebrew/Cellar/node/23.11.0/bin/node]

Expected Behavior

  • State file should either be pruned/rotated automatically to prevent excessive growth
  • JSON parsing should be more memory-efficient for large state files
  • Should handle large state files gracefully without crashing

Suggested Fixes

  1. Implement state file rotation or pruning when it exceeds a certain size (e.g., 1MB)
  2. Use streaming JSON parsing for large state files
  3. Increase default Node.js heap size for Claude Code
  4. Add state file size monitoring and warnings
  5. Implement incremental state persistence rather than full file writes

Workaround

Users can temporarily work around this by:

  • Deleting or backing up the .claude.json file
  • Starting Claude Code with increased heap: NODE_OPTIONS="--max-old-space-size=4096" claude

Additional Context

  • The crash occurred after approximately 47 hours of runtime (168954279 ms)
  • Memory usage at crash: ~2GB
  • State file had 66 startups recorded

View original on GitHub ↗

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