「Memory index read limit」の対処 — Claude Code
Claude CodeのMEMORY.mdが200行/25KBを超えると、書き込みは成功しても超過分がセッション開始時に読み込まれなくなります。原因と縮め方をまとめます。
Claude Codeがauto memoryの索引MEMORY.mdに書き込んだ直後に「Memory index is over its read limit」と出ることがあります。この場合、書き込みそのものは成功しています。問題は次回以降のセッションです。
MEMORY.mdは200行か25KBの、先に達したほうまでしか読み込まれません。そこから先の内容は、セッションが始まるたびに読み飛ばされます。
エラーの文面と、書き込みが成功している意味
表示される文言は次のとおりです。
Error: this write left the memory index at MEMORY.md at 214 lines, over its 200-line read limit. The write succeeded, but everything past the limit is silently dropped each time the index is loaded — entries at the end are already invisible to readers. Rewrite it to under 140 lines now: keep one line per entry, move detail into topic files, and merge or drop stale entries.この文面は、ターミナルにバナーとして出るものではありません。書き込みが終わったあと、Claudeへの応答として渡されます。ユーザーが気づくのは、トランスクリプトを読み返したときになりやすい形です。
「The write succeeded」とあるとおり、エラーが出た書き込みをやり直す必要はありません。必要なのは、索引を140行未満へ書き直す追加の編集だけです。
MEMORY.mdの読み込み上限
行数
200行
先頭から数える
サイズ
25KB
先頭から数える
書き直しの目標
140行未満
エラー文が示す安全圏
140行という数字は、上限の200行とは別物です。ぎりぎり200行に収めると次の書き込みでまた超えるため、余裕を持たせた目標が示されています。
気づかないまま失うのは、末尾に書いたエントリ
MEMORY.mdはauto memoryディレクトリの索引です。読み込まれるのは先頭側だけなので、追記を重ねるほど、最近書いたエントリが読み飛ばされる側に入ります。
上限を超えても、その場では何も止まりません。次のセッションでClaudeが前回の学びを使っていないと感じたとき、原因が索引の末尾切れという可能性があります。古いエントリを整理しないまま新しい内容を足し続けると、いちばん新しい記憶から消えていく順番です。
上限に近づいただけの段階では、エラーではなく軽いリマインダーが返ります。索引を圧縮するよう促す内容です。上限を超えたときにエラーへ切り替わります。
数えられるのは、実際に読み込まれる内容だけ
測定の対象は、セッション開始時に読み込まれる内容です。YAMLのfrontmatterと、ブロックレベルのHTMLコメントは、索引が読み込まれる前に取り除かれます。そのため行数にもバイト数にも入りません。
エラーの扱いが変わった2つのバージョン
- v2.1.210より前書き込み時の知らせがない
上限を超えた索引は、次に読み込まれるときに黙って切り詰められるだけでした。
- v2.1.211より前生のファイルを測定
frontmatterやコメントが多いだけで、読み込まれる内容は上限内なのにエラーが出ることがありました。
- v2.1.211以降読み込まれる内容だけを測定
frontmatterとブロックレベルのHTMLコメントを除いた分量で判定します。
v2.1.210以上v2.1.211未満の版で、frontmatterやコメントのせいで想定外の上限エラーが出た場合は、まずclaude --versionでバージョンを見る価値があります。
手元の索引が上限のどこにいるかを数える
エラーを待たなくても、自分のMEMORY.mdがどこまで来ているかは数えられます。下の例は、frontmatterと1行コメントを除いた行数とバイト数を出す簡易スクリプトです。Claude Code本体の計測そのものではなく、公式が説明している除外ルールに合わせた近似です。複数行にまたがるHTMLコメントは取り除けないので、使っている場合は差が出ます。
次の出力は、frontmatter3行とコメント1行を付けた、本文214行の索引で試した結果です(Claude Code v2.1.289の環境で実行)。
awk 'NR==1&&$0=="---"{f=1;next} f&&$0=="---"{f=0;next} f{next} /^<!--.*-->$/{next} {print}' MEMORY.md > loaded.txt
wc -l < MEMORY.md # 生のファイル
wc -l < loaded.txt # frontmatter・コメントを除いた行数
wc -c < loaded.txt # 同じくバイト数218
214
10912生のファイルは218行ですが、読み込み対象とみなすのは214行です。この例は200行を14行超えていますが、バイト数は約10.9KBで、25KBにはまだ届いていません。
逆の場合もあります。25KBを200行で割ると、1行あたり125バイト前後です。UTF-8では日本語1文字が3バイトなので、1行が約40字を超える索引が続くと、200行より先に25KBへ着きます。1エントリ1行を守っても、1行が長ければバイト数の側で上限に当たります。
実際の索引を測るときは、MEMORY.mdの場所を~/.claude/projects/<project>/memory/の下から探します。
症状から原因を切り分ける
エラーが出ないまま「前回の内容が使われていない」場合は、原因が複数あります。
| 症状 | 疑う点 | 確かめ方 |
|---|---|---|
| エラーが出た | 疑う点超過後の書き込み | 確かめ方後述の手順で140行未満へ |
| エラーは出ないが末尾のエントリが使われない | 疑う点v2.1.210より前のバージョン | 確かめ方claude --versionで確認。書き込み時の知らせがなく、次の読み込みで切り詰められるだけ |
| 行数は200未満なのに切れる | 疑う点1行が長く、25KBに先に到達 | 確かめ方wc -cでバイト数を見る |
| トピックファイルの内容が出てこない | 疑う点起動時には読まれない仕様 | 確かめ方Claudeに該当ファイルを読ませる |
Claudeが記憶を書くときや読むときは、インターフェースに「Saved 2 memories」「Recalled 2 memories」のような表示が出ます。Claudeは毎セッション何かを保存するわけではなく、将来の会話で役立つかどうかで保存するかを決めます。表示が出ないこと自体は、異常を意味しません。
超過したときの縮め方
索引を140行未満に戻す
- 1
Claudeに書き直しを頼む
エラーはClaudeに返るため、Claudeがそのまま整理することもあります。入らないときは「
MEMORY.mdを1エントリ1行にして140行未満にして」と頼めば足ります。 - 2
詳細をトピックファイルへ移す
経緯や手順は
feedback_testing.mdのような個別ファイルへ移し、索引には「何がどこにあるか」の1行だけ残します。 - 3
古いエントリを統合・削除する
もう参照されない記録は、近い内容と統合するか消します。
- 4
自分で直したいときは/memoryを使う
/memoryでauto memoryフォルダを開き、MEMORY.mdと各トピックファイルを編集します。中身は素のMarkdownです。
Claudeに任せる場合も自分で直す場合も、書き直し後は先ほどの数え方で行数を確かめておくと、次の書き込みで再発するかどうかを事前に見分けられます。
索引とトピックファイルの役割分担
auto memoryディレクトリは、索引1つとトピックファイルの集まりでできています。
~/.claude/projects/<project>/memory/
├── MEMORY.md # 簡潔な索引。毎セッション読み込まれる
├── user_role.md # トピックファイル
├── feedback_testing.md # トピックファイル
└── ...読み込まれるタイミングの違い
MEMORY.md
先頭200行か25KBまでが、会話の開始時に読み込まれます。道しるべとして短く保つ前提です。
トピックファイル
起動時には読み込まれません。必要になったときに、Claudeが通常のファイル操作で読みに行きます。
詳細を移す先がトピックファイルなのはこのためです。ここに移した内容は、上限に数えられません。
メモリーのファイルは、古いセッションの記録を消す定期的な掃除(cleanupPeriodDays)の対象外です。索引もトピックファイルも、Claudeか自分が編集・削除するまで残り続けます。放っておいて自然に縮むことはないので、整理は手動かClaude経由になります。
なお、frontmatterを持つメモリーファイルには、Claudeが書き込んだ時刻がmodifiedフィールドとして入ります(v2.1.214以降)。frontmatterは計測から除かれるため、この時刻が索引の行数を押し上げることはありません。
この仕組みの設定面はauto memoryの設定項目、CLAUDE.mdや.claude/rules/との層の分け方はメモリー3層の使い分けで扱っています。
読み込まれたかどうかを/contextで確かめるときの注意
/contextの「Memory files」には、そのセッションで読み込まれたファイルが並びます。見えるのはファイルの単位です。MEMORY.mdの何行目まで読まれたかまでは、この一覧からは分かりません。
「書いたはずのエントリが使われていない」と感じたときは、/contextでMEMORY.mdが載っているかを見たうえで、先ほどの数え方でエントリが200行目の内側にあるかを確かめるのが近道です。
CLAUDE.mdには同じ上限がない
200行・25KBの上限が働くのはMEMORY.mdだけです。CLAUDE.mdは、4MiBを超えるファイルを読み込まないという別の制限を除けば、全文が読み込まれます。
その代わり、CLAUDE.mdは200行を超えるとコンテキストを多く使い、指示への従い方が落ちやすくなります。長くなったときは、パス限定ルールで、該当するファイルを扱うときだけ読ませる手があります。@pathのインポートは起動時に全文が読み込まれるため、コンテキストの消費は減りません。
長すぎる指示ファイルには、起動時と/statusで警告が出ます。個々のファイルが基準内でも、合計が上限を超えると警告されます。数えるのはCLAUDE.md・rulesファイル・@pathのインポートの1つずつです。MEMORY.mdの超過は警告ではなく、Claudeに返るエラーとして現れるため、見え方が違います。
auto memoryはClaudeが書き、CLAUDE.mdは人が意図して書くという違いがあります。「pnpmを使う、npmは使わない」のような指示をClaudeに伝えるとauto memoryに保存されます。プロジェクトの決まりとして固定したいものは、「CLAUDE.mdに追加して」と頼むか、/memoryから自分で書きます。
保存場所は同じリポジトリの中で共有される
プロジェクトごとのディレクトリは、Gitリポジトリから決まります。同じリポジトリの中なら、worktreeやサブディレクトリが違っても、auto memoryのディレクトリは1つです。Gitリポジトリの外では、プロジェクトのルートが使われます。
一方、別のマシンやクラウド環境とはファイルが共有されません。あるマシンで学習した内容を、別のマシンのClaude Codeが知らないのはこの仕組みのためです。置き場所はautoMemoryDirectory設定で変えられますが、200行・25KBの上限とは別の話です。
よくある質問
サブエージェントのauto memoryにも同じ上限がありますか
サブエージェントがmemoryフィールドで持つauto memoryも、同じMEMORY.mdの仕組みで動きます。上限の数字は、メインの会話の索引と同じ200行・25KBです。
メインの会話のauto memoryは、サブエージェントには読み込まれません。例外は、会話をフォークして起動するサブエージェントです。この場合は親の会話とシステムプロンプトを引き継ぎます。
auto memoryを切ればエラーは出なくなりますか
MEMORY.mdへの自動書き込みが起きなくなるため、このエラーも出ません。/memoryのトグル、プロジェクトの設定のautoMemoryEnabledをfalseにする方法、環境変数CLAUDE_CODE_DISABLE_AUTO_MEMORY=1のいずれでも切れます。
引き換えに、Claudeが学んだ内容は次のセッションへ持ち越されません。
なお、バックグラウンドセッションや、別のClaude Codeセッションが起動したセッションでは、トグルでオフにはできてもオンには戻せません。その場合のトグルは「off · can't be turned on here; use a session started outside Claude Code」と表示されます。オンに戻すには、ターミナルでclaudeを直接起動したセッションで/memoryのトグルを使います。
まとめ
エラーが出たら、書き込みは無事で、次回の読み込みから超過分が消えているだけです。索引を1エントリ1行に縮め、詳細はトピックファイルへ移すことで戻ります。
エラーを待たずに行数とバイト数を数えておけば、超過に先に気づけます。日本語で索引を書いているなら、1行を40字程度までに抑えるのが、バイト数の上限を避ける目安です。