Claude Codeが「JavaScript heap out of memory」で落ちる原因を、GitHub Issueの実例で整理した
Claude Codeが「FATAL ERROR: JavaScript heap out of memory」でクラッシュする原因を解説。.claude.json肥大化・長時間セッション・--resume・MCP重処理の4パターンをGitHub Issue実例つきで整理し、NODE_OPTIONSでの即効対処から恒久対策まで手順化した。
エンジニアのゆとです。
Claude Codeで作業していたら、ある瞬間に画面が止まってFATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memoryとだけ吐き出されて、セッションごと死ぬ——という経験をした人はそれなりにいると思う。会話の途中でこれをやられると、直前まで積み上げていたコンテキストが全部消える。地味に精神を削られる系のエラーだ。
「メモリ不足」で検索すると、大規模プロジェクト解析でメモリを食う一般論か、逆にインストール時点のKilledの話ばかり出てきて、このFATAL ERRORそのものがどんな条件で起きるかを実例ベースで整理した記事は少ない。今回はGitHub Issueに報告されている実例を軸に、発生パターンと対処法をまとめた。
まず結論 — 暫定対処はNODE_OPTIONS、根本原因は4パターンに分かれる
このエラーの正体は、Claude Codeの実行基盤であるNode.jsのV8エンジンが、確保できるメモリ(ヒープ)の上限に達してクラッシュした状態だ。Node.jsのデフォルトのヒープ上限は環境にもよるが1.4〜1.7GB程度と、Claude Codeが長時間・大規模に使われる場合には心もとない値になっている。
とりあえず今すぐ止血したいなら、次のコマンドでヒープ上限を引き上げてから起動する。
NODE_OPTIONS="--max-old-space-size=8192" claude
これで大抵の場合は落ちなくなる。ただしこれは「症状を抑える」対処であって、なぜメモリを食い潰しているのかという根本原因は別に潰す必要がある。GitHub Issueを見ていくと、原因は大きく4パターンに分類できた。
- 長時間セッションでのガベージコレクション(GC)失敗
.claude.json状態ファイルの肥大化--resumeでの大量履歴読み込み- 巨大ディレクトリの一覧化・重いMCP処理
以下、それぞれ実例つきで見ていく。
そもそも「メモリ不足」は3種類ある——混同すると対処を間違える
本題に入る前に、ここを整理しておく。Claude Code関連で「メモリ不足」と呼ばれる症状は、実は性質の異なる3つが混ざって語られていることが多い。
1つ目は、インストール時点でLinuxのOOM Killerにclaude installプロセスごと殺されるKilled。これは今回の話とは別物で、格安VPSなどRAMが512MB〜1GB程度の環境で起きる。この記事の対象ではないので、該当する人はこちらを見てほしい。

2つ目は、システムの空きメモリとスワップが逼迫することで、Claude Codeの応答が「なんとなく遅い」「幻聴のような的外れな返答をする」といった劣化症状を起こすケース。これはプロセスがクラッシュするわけではなく、じわじわ挙動が悪化するタイプで、実測データをもとに別記事で扱っている。

3つ目が、今回扱うFATAL ERROR: JavaScript heap out of memoryだ。これはNode.jsプロセスのヒープが上限に達し、Claude Codeのセッションそのものが強制終了するタイプで、上の2つとは発生条件も直し方もまったく違う。まずここを混同しないことが、正しい対処への近道になる。
なお「重い・遅い」全般の切り分けについては、公式の診断コマンドを使った原因の階層整理を別記事で書いているので、クラッシュまではしていないケースはそちらを先に見たほうが早いかもしれない。

「JavaScript heap out of memory」が起きる4パターン
パターン1: 長時間セッションでのGC失敗
もっとも典型的なのが、セッションを長時間動かし続けた末にヒープが枯渇するケースだ。
GitHub Issueに報告されている実例では、約14.6時間(52,593,403ミリ秒)連続で動かしていたセッションが、ファイル読み込みのタイミングでクラッシュしている。
FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
node::fs::ReadFileUtf8()
Mark-Compact GC: 4344.4 → 4343.8 MB
Mark-Compact GC(マーク・コンパクト方式のガベージコレクション)を実行しても、確保しているメモリがほとんど減っていない。つまり「解放できるはずのメモリがない」状態まで来ていて、これ以上どうやってもメモリを確保できずに力尽きている。
この手のケースで見落としがちなのが、サブプロセスの出力だ。Claude Codeはアイドル時400〜700MB程度で収まるが、git・npm install・pytestのような外部コマンドを実行すると、その標準出力・標準エラー出力がヒープ上に保持され続ける実装になっている。1回1回の出力は小さくても、長時間のセッションで何十回とサブプロセスを叩けば、線形にメモリが積み上がっていく。単一セッションで3.3GBまで膨らんだという報告もあるくらいだ。
つまり「長く使っているだけ」でもメモリは減っていく方向にしか動かない。これがパターン1の正体だ。
パターン2: .claude.json状態ファイルの肥大化
意外と知られていないのがこのパターンで、GitHub Issueでは.claude.jsonというホームディレクトリ直下の状態管理ファイルが8.4MB(3,475行)まで膨らみ、それをパースする過程でクラッシュした事例が報告されている。
.claude.json: 8.4MB(3,475行)
↓ JSON.parse()で全体を一括読み込み
Mark-Compact GC: 2007.4MB → 1978.0MB(回復不十分)
↓
最終GC: 1994.7MB → 1994.7MB(回復失敗)
↓
JsonParser::MakeString() でメモリ確保失敗
↓
FATAL ERROR: JavaScript heap out of memory
このケースでは起動回数(numStartups)が66回、実行時間47時間分のセッション履歴などが.claude.jsonに蓄積し続けており、ファイル全体を毎回JSON.parse()で一括読み込みする実装が、肥大化とともにヒープを圧迫していた。
.claude.jsonは~/.claude/backupsに最大5世代までバックアップが自動でローテーションされる仕組みも用意されているが、本体側の肥大化そのものを止める機構ではないため、長期間同じ環境で使い続けると起きうる問題として覚えておいたほうがいい。
パターン3: --resumeでの大量履歴読み込み
過去のセッションを再開する--resumeコマンドでも、同種のクラッシュが報告されている。原因は.claude.jsonと似ていて、会話履歴が長大な場合に、それを丸ごとメモリに読み込もうとしてNode.jsのデフォルトヒープ上限を超えてしまうというものだ。
長期間触っているプロジェクトほど再現しやすく、--resumeを多用する運用スタイルの人ほど当たりやすい。
パターン4: 巨大ディレクトリの一覧化・重いMCP処理
最後は、ファイルシステムやMCPサーバー越しに大きなデータを一度に扱おうとして落ちるケースだ。数百パス規模のディレクトリを一覧化する操作や、MongoDBなど外部データソースを扱うMCPサーバーで大きな配列を処理する操作で、同様のクラッシュが報告されている。
MCPサーバー自体が繋がらない・応答しないという別種の不具合については、公式ドキュメントの症状別対処表をベースに整理した記事があるので、あわせて見ておくと切り分けが早い。

暫定対処 — NODE_OPTIONSでヒープ上限を増やす
原因がどのパターンであっても、まずやるべきはヒープ上限を引き上げることだ。Anthropic自身が公開しているdevcontainerの設定でも、次の値が使われている。
NODE_OPTIONS="--max-old-space-size=4096" claude
サブエージェントを並列で動かしたり、大規模なモノレポを扱ったりする場合は、もう一段階上げて8GBにしておくと安全マージンが大きい。
NODE_OPTIONS="--max-old-space-size=8192" claude
毎回コマンドの前に打つのが面倒なら、シェルの設定ファイルに恒久的に書いておく。
# ~/.zshrc または ~/.bashrc に追記
export NODE_OPTIONS="--max-old-space-size=8192"
source ~/.zshrc
ここで注意したいのは、--max-old-space-sizeは「使えるメモリの天井を上げる」だけで、メモリの使い方自体を効率化するものではないという点だ。物理RAMが4GB程度しかないマシンで8192を指定しても、今度はOS側のスワップが発生して別の遅さに転化するだけになる。搭載RAMに見合った値を選ぶのが前提になる。
恒久対処 — 原因別に潰す
.claude.jsonを安全に整理する
パターン2に当たっている場合は、肥大化した.claude.jsonを整理する。中にはOAuthトークンやMCPサーバーの認証情報が入っているファイルなので、雑に消すのは避けて、必ずバックアップを取ってから作業する。
# 1. Claude Codeを終了した状態で実行する
cp ~/.claude.json ~/.claude.json.bak
# 2. ファイルサイズを確認する
ls -lh ~/.claude.json
# 3. 数MBを超えて肥大化している場合、いったん退避してから起動し直す
mv ~/.claude.json ~/.claude.json.old
claude
新しい.claude.jsonが再生成されれば、認証情報を含む設定は起動時の認証フローで再構築される(MCPサーバーの個別設定は入れ直しが必要になる場合がある)。~/.claude/backupsにも直近5世代のバックアップが自動保存されているので、何か消しすぎた場合はそちらから復元できないか確認するといい。
タスクを分割してスコープを絞る
パターン1・パターン4のように、扱う情報量そのものが多すぎて起きているケースには、Claude Codeに投げる作業単位を小さくするのが効く。
- ディレクトリ単位で段階的に処理させる(リポジトリ全体を一度に読み込ませない)
- 対象ファイルをパターンで明示的に絞る(
src/**/*.tsのように) - 読み取り専用の調査タスクと、書き込みを伴う実装タスクを分けて依頼する
- CLAUDE.mdに「大きな処理は一気にやらず、段階的に進める」と明記しておく
とくに最後のCLAUDE.mdへの指示は効果が体感しやすい。Claude Code自身に「今どのくらいの情報量を扱っているか」を意識させることで、無茶な一括処理を避けてくれるようになる。
--resumeは履歴が長すぎないか確認する
パターン3に心当たりがある場合、--resumeで開こうとしているセッションの履歴サイズを疑ったほうがいい。会話が長期化しているプロジェクトでは、思い切って新しいセッションとして仕切り直し、必要な文脈だけをCLAUDE.mdやメモファイルに要約して引き継ぐほうが、結果的に安定する。
「メモリリークかも」と決めつける前に確認すること
正直に書いておくと、Claude Codeそのものの不具合だと思って調べていくと、原因が別のところにあったというオチも意外と多い。
たとえば「20〜40GBもメモリを食っている」という報告を検証したケースでは、原因はClaude Code本体ではなく、ユーザー自身が設定したカスタムオーディオフック(通知音を鳴らす仕組み)だったという例がある。アイドル時に不自然な高メモリ消費が見られたら、まず自分で追加したhooks・カスタムMCPサーバー・拡張機能を疑うのが正しい順番だ。
claude --safe-modeで起動すれば、そのセッション中はプラグイン・MCP・hookがすべて無効化される。これで症状が消えるなら、Claude Code本体ではなく拡張機能側が原因だったと確定できる。
FAQ
NODE_OPTIONSを設定しても直らない場合は?
ヒープ上限を8192まで上げても落ちるなら、単純な上限不足ではなく、パターン2(.claude.json肥大化)やメモリリーク的な挙動を疑ったほうがいい。/heapdumpコマンドでヒープスナップショットを取得し、何が大量に確保されているか確認するのが次の一手になる。ヒープスナップショットには会話内容や認証情報がそのまま含まれるため、GitHub Issueなどに添付する際は統計情報のみの-diagnostics.jsonの方を使うこと。
claude --versionを最新にすれば直る?
Anthropicはメモリ関連のバグを継続的に修正しているため、古いバージョンを使い続けている場合はアップデートだけで改善することがある。まずclaude updateでバージョンを上げてから、それでも再現するか確認するのが手順として早い。
Windows/WSL2でも同じ対処でいい?
NODE_OPTIONSによるヒープ上限の引き上げ自体はOS非依存で有効だ。ただしWSL2の場合、Windows側とLinux側でメモリ割り当てが分かれているため、.wslconfig側のメモリ上限も合わせて確認したほうがいい。WSL2の設定不備が別種の遅さの原因になっているケースもあるので、心当たりがあれば環境構築側から見直すのも手だ。
まとめ
FATAL ERROR: JavaScript heap out of memoryは、Node.jsのヒープ上限に達したという一点では共通しているが、実際の引き金はセッションの長さ・.claude.jsonの肥大化・--resume・巨大データの処理と、原因によって直し方が変わってくる。
とりあえずNODE_OPTIONS="--max-old-space-size=8192"で止血しつつ、自分がどのパターンに当てはまるかを切り分けて、根本原因の方を潰していくのが遠回りに見えて一番早い。