「Transcript writes are failing」の対処 — Claude Code
入力欄の下に出るTranscript writes are failing警告の原因と直し方を解説します。原因はエラーコードで名指しされるため、対処は機械的に決まります。
このTipsでできること
作業中の入力欄の下にTranscript writes are failingという警告が常設で出ることがあります。セッション自体は止まらず作業も続けられますが、放置すると後で--resumeしたときに直近のやり取りが消えている可能性があります。
この記事では、警告が出る条件、エラーコードごとの直し方、似た文言のTranscript saving is offとの見分け方を扱います。保存が止まっている間に会話を守る手段も、実際に使える範囲に絞って書きます。
なぜ「Transcript writes are failing」が出るか
Claude Codeは作業中の会話を~/.claude/projects/<project>/<session-id>.jsonlへ逐次書き込んでいます。このファイルへの書き込みが失敗すると、入力欄の下に警告が出ます。警告にはOSのエラーコードが添えられ、原因が名指しされます。
Transcript writes are failing (disk full — ENOSPC) · recent messages may not be saved for resume警告が出るタイミングはエラーの種類で変わります。ディスクフル(ENOSPC)、クォータ超過(EDQUOT)、読み取り専用ファイルシステム(EROFS)、パス長超過、macOS・Linuxでの権限エラーは、自然には解消しない条件です。これらは最初の失敗で即座に警告になります。
それ以外はWindowsでの権限エラーを含め、1分以上続けて失敗したときだけ警告になります。ウイルススキャンのせいで1回の書き込みが失敗しても、次のリトライで成功することがあるためです。
警告が出ていても会話とツール実行は止まりません。影響を受けるのはディスクへの保存だけです。
警告が出たときの流れ
- 1
エラーコードを読む
警告の括弧内(
ENOSPCなど)が原因です。推測で探す必要はありません。 - 2
コードが指す条件を直す
容量・クォータ・権限・マウント状態のどれかを、次の表に沿って直します。
- 3
次の書き込みを待つ
直したあとにメッセージを送れば、書き込みが成功した時点で警告が消えます。再起動は不要です。
エラーコード別の直し方
| エラーコード | 原因 | 対処 |
|---|---|---|
ENOSPC | 原因ディスク容量不足 | 対処空き容量を確保する |
EDQUOT | 原因ディスククォータ超過 | 対処クォータを引き上げるか解消する |
EACCES / EPERM | 原因書き込み権限がない | 対処トランスクリプトの保存先の書き込み権限を戻す |
EROFS | 原因読み取り専用のファイルシステム | 対処保存先に書き込めるようにする |
| パス長超過 | 原因ファイルシステムの長さ上限を超えた | 対処保存先のパスを短くする(回避策は後述) |
Linux・macOSでは、次のコマンドで容量と権限の両方を確認できます。
# ディスクの空き容量を確認
df -h ~/.claude
# 保存先ディレクトリの権限を確認
ls -ld ~/.claude/projectsトランスクリプトのディレクトリ名は、作業ディレクトリのパスの英数字以外を-に置き換えて作られます。変換後の名前が200文字を超えると、Claude Codeは200文字に切り詰め、パス全体のハッシュを末尾に付けます。
それでもパス長超過の警告が出る環境では、CLAUDE_CONFIG_DIRに短いパスを指定して保存先を移すのが一案です。v2.1.234以降なら、CLAUDE_CODE_PROJECT_DIR_NAMEを組み合わせてディレクトリ名も固定できます。公式がパス長の対処として挙げているわけではなく、変数の仕様から考えた回避策です。
CLAUDE_CONFIG_DIR=/srv/tenant-a CLAUDE_CODE_PROJECT_DIR_NAME=work claudeこの場合、トランスクリプトは/srv/tenant-a/projects/work/に書かれます。CLAUDE_CONFIG_DIRを指定しないと、この変数は無視されます。settingsファイルのenvブロックでは指定できず、claudeを起動するシェルの環境から渡す必要があります。
同じCLAUDE_CONFIG_DIRのままCLAUDE_CODE_PROJECT_DIR_NAMEを付けずに起動すると、元の派生名のディレクトリを再び読み書きします。セッションピッカーでCtrl+Aを押せば、どちらの名前の下のセッションも一覧できます。
警告が出ていた間のメッセージは戻らない
原因を直したあとに書き込みが成功すれば警告は消えますが、警告が出ていた間に送ったメッセージは、後から--resumeしても欠けている可能性があります。警告を消しても、欠けた分をさかのぼって保存し直す仕組みは公式の説明にありません。
会話が長く続いていたなら、直す前に/exportで書き出しておく選択肢があります。/exportは現在の会話を、クリップボードへのコピーか読みやすい平文ファイルとして出力するコマンドです。ファイル名を渡すとメニューを飛ばして直接書き出します。
ディスクフルが原因なら、書き出し先は別のボリュームにします。同じディスクへ書こうとして同じエラーになるのを避けるためです。
v2.1.217より前は警告なしで書き込みが失われていた
この警告はv2.1.217で加わりました。それ以前のClaude Codeは、書き込みに失敗しても何も表示せず、取りこぼしに気づくのは後日の--resumeでした。changelogには「トランスクリプトを黙って失う代わりに警告を出す」と書かれています。
disk fullのような手がかりも出なかったため、原因の特定は難航しがちでした。今は失敗の時点で警告が出て、エラーコードまで名指しされます。
v2.1.217のリリースノートには、同じ版の変更として同時実行サブエージェント数の上限(既定20、CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTSで変更)も入っています。警告が出ない環境がv2.1.217より前でないかは、claude --versionで確かめられます。
「saving is off」は失敗ではなく保存オフの通知
Transcript writes are failingとよく混同されるのが、Transcript saving is offで始まる別の通知です。前者は保存を試みて失敗している状態、後者は保存しない設定になっている状態です。
同じ「保存されない」でも原因が違う
Transcript writes are failing
保存しようとして書き込みが失敗しています。エラーコードの条件を直せば、次の書き込みで警告が消えます。
Transcript saving is off
保存しない条件が成立している通知です。意図した設定なら対処は不要で、意図しないなら環境変数を外して起動し直します。
Transcript saving is offには、次の2種類があります。実際の文言は公式のエラー一覧にあるとおりです。
Transcript saving is off — CLAUDE_CODE_SKIP_PROMPT_HISTORY is set · --resume will not find this session; if unintended, unset it and restartTranscript saving is off — inherited CLAUDE_CODE_CHILD_SESSION marker · restart with CLAUDE_CODE_FORCE_SESSION_PERSISTENCE=1 to keep future transcripts
CLAUDE_CODE_SKIP_PROMPT_HISTORYは、使い捨てのスクリプト向けに保存を止めるための変数です。シェルプロファイル、ラッパースクリプト、親プロセスがexportしていて、気づかないうちに届くこともあります。意図せず設定されていたなら、その変数を外して新しいセッションを始めます。現在のセッションの分は、あとから保存されません。
CLAUDE_CODE_CHILD_SESSIONのほうは、Claude Codeが起動するBash・フック・ステータスラインなどのサブプロセスに付くマーカーです。これを引き継いだ対話セッションは入れ子として扱われ、保存されません。Claude Codeの中からもう1つclaudeを起動すれば通知が出るのは想定どおりの挙動です。
一方、screenやランチャーなど、長く生きる仲介プロセスを経由してマーカーが漏れた場合は、最上位のセッションが入れ子と誤判定されます。この場合はCLAUDE_CODE_FORCE_SESSION_PERSISTENCE=1を付けて起動し直します。同じターミナルやランチャーからの以後の起動を直すには、その環境からCLAUDE_CODE_CHILD_SESSIONを外します。どちらも保存は再起動から有効になり、それ以前に送ったメッセージは保存されません。tmuxでは、tmuxサーバーのグローバル環境経由で届いたマーカーをv2.1.178以降が自動で無視します。
複数セッションを親子関係で動かすagent viewのようなバックグラウンドセッション運用では、この継承に当たる場面が増えます。なお対話TUIの入れ子は--resume・--continue・上矢印の履歴・claude agents一覧から外れますが、非対話のclaude -pは保存されます。
保存を意図して止めるなら--no-session-persistence
CIやスクリプトからclaude -pを呼ぶとき、その1回だけ保存したくないことがあります。その場合は環境変数より、--no-session-persistenceが向いています。
手元のv2.1.285でclaude --helpを確認すると、次の説明が出ます。
claude --version
# 2.1.285 (Claude Code)
claude --help | grep -A3 -- "--no-session-persistence"
# --no-session-persistence Disable session persistence - sessions
# will not be saved to disk and cannot be
# resumed (only works with --print)末尾の「only works with --print」が要点で、対話セッションでは使えません。対話も含めてすべてのモードで止めたいなら、CLAUDE_CODE_SKIP_PROMPT_HISTORYを使います。ただし環境変数は、呼び出し元のシェルやプロセスから他の実行へ引き継がれやすい点に注意が必要です。フラグならコマンド1回に限定でき、たまたま書き込みに失敗したのか、意図して止めているのかが呼び出し側で区別できます。
長時間セッションでの再発を避ける
トランスクリプトは既定で30日間保持され、cleanupPeriodDaysで変更できます。値は1以上の整数で、0は検証で弾かれます。
{
"cleanupPeriodDays": 14
}上のような設定は~/.claude/settings.jsonなどのsettingsファイルに書きます。ただし保持期間を短くすると、ディスクは空きますが、その期間を過ぎたセッションは/resumeの一覧から消えます。削除はバックグラウンドで、メッセージなしに行われます。
容量そのものが足りないなら、CLAUDE_CONFIG_DIRで~/.claudeとは別のボリュームを指定し、保存先を移す方法もあります。この変数はプロジェクト設定・ローカル設定では無視されるため、シェルの環境かユーザー設定、managed settingsで指定します。セッションを快適に保つ運用の工夫も、ディスク以外の要因で長時間セッションが重くなるときに参考になります。
SessionEndフックのバックアップは万能ではない
SessionEndフックの入力には、セッションのトランスクリプトを指すtranscript_pathが含まれます。終了時にこのファイルを別の場所へコピーするフックは書けますが、警告の回避策としては限界があります。
理由は2つあります。第一に、transcript_pathのファイルは非同期に書かれ、メモリ上の会話より遅れることがあると公式が明記しています。第二に、書き込みに失敗していたメッセージはそもそもそのファイルに入っていません。コピーできるのは保存済みの範囲だけで、失った分は戻りません。
つまりフックが役立つのは、EDQUOTのように「保存先が使えなくなる前の分を別の場所に残したい」場面です。警告が出ているセッションの取りこぼしを埋める手段としては、前述の/exportのほうが直接的です。
まとめ
エラーコードが原因を名指しするので、直す先は容量・クォータ・権限・マウント状態・パス長のどれかに決まります。ただし警告が出ていた間の会話は、直しても戻らない可能性があります。長い会話を抱えているなら、直す前に/exportで別ボリュームへ書き出しておくと、最悪の場合の損失を抑えられます。