CLAUDE_CODE_RESUME_PROMPTとMAX_AGE_MSで自動再開を調整する
中断ターンの自動再開メッセージと、再開を諦めるまでの経過時間をCLAUDE_CODE_RESUME_PROMPTとMAX_AGE_MSで調整する方法をまとめます。
CLAUDE_CODE_RESUME_INTERRUPTED_TURNの自動再開とは
CLAUDE_CODE_RESUME_INTERRUPTED_TURNは、前回のセッションがターンの途中で終わったときに自動で再開させる環境変数です。SDKモードでの利用を想定しており、1を設定するとClaude Codeが続きから応答を返し、呼び出し側のアプリケーションがプロンプトを再送信する必要がなくなります。
この自動再開は「どんな文言で続きを促すか」と「どこまで古いセッションなら再開してよいか」の2点を追加の環境変数で細かく制御できます。CLAUDE_CODE_RESUME_PROMPTが前者、CLAUDE_CODE_RESUME_INTERRUPTED_TURN_MAX_AGE_MSが後者です。
止め方にはバージョンによる注意点があります。v2.1.221より前のClaude Codeは非対話モードで0などの偽値を無視するバグがあり、CLAUDE_CODE_RESUME_INTERRUPTED_TURN=0と設定しても再開が発動していました。無効化するには変数そのものをunsetする必要があった、という経緯です。
CLAUDE_CODE_RESUME_PROMPTで継続メッセージを差し替える
CLAUDE_CODE_RESUME_PROMPTは、CLAUDE_CODE_RESUME_INTERRUPTED_TURNが中断ターンを継続するとき、あるいは後述するdeferされたツール呼び出しを-pで再開するときに、Claude Codeが送る継続メッセージを上書きします。
既定値はContinue from where you left off.です。空文字列を設定すると既定値に戻ります。
export CLAUDE_CODE_RESUME_INTERRUPTED_TURN=1
export CLAUDE_CODE_RESUME_PROMPT="続きから作業を再開してください。"
claude -p --resume <session-id>継続メッセージを差し替える場面は、SDKアプリ側で独自のUIを持ち、ユーザーへの表示文言とClaudeへ送る継続文言を揃えたいときです。既定文言のままだと、ログや監査画面に無機質な英語文が残り続けるため、日本語UIのプロダクトでは差し替えの需要があります。
deferされたツール呼び出しを-pで再開するときの継続メッセージ
CLAUDE_CODE_RESUME_PROMPTのもう一つの出番は、hookがpermissionDecision: "defer"を返したセッションを-pで再開するときです。典型的なケースはAskUserQuestionです。ユーザーに何かを尋ねたくても、-pで動かしているプロセスには答えを打ち込む端末がありません。deferはこの状況で、呼び出し側のプロセスがツール呼び出しの時点でClaudeを一時停止させ、自前のUIで入力を集めてから続きを再開できるようにする仕組みです。仕組みを順番に見ると、この文言がどこで使われるかがはっきりします。
- Claudeが
AskUserQuestionのようなツールを呼び出し、PreToolUseフックが発火する - フックが
"defer"を返すと、ツールは実行されずプロセスはstop_reason: "tool_deferred"で終了し、保留中のツール呼び出しがtranscriptに残る - 呼び出し側のアプリケーションはSDKの結果から
deferred_tool_useを読み取り、自前のUIで質問を表示して回答を待つ - 回答が揃ったら
claude -p --resume <session-id>で同じパーミッションホストを指定して再開し、同じツール呼び出しに対してPreToolUseが再度発火する - フックが
updatedInputに回答を入れて"allow"を返すと、ツールが実行され続きが進む
"defer"は非対話モード(-pフラグ)でのみ有効で、対話セッションでは警告を出して無視されます。また、Claudeが1ターンで複数のツールを同時に呼び出した場合も"defer"は無視され、警告とともに通常の権限フローに進みます。resumeで再実行できるツール呼び出しは1件だけなので、複数のうち1件だけを保留すると残りが取り残されてしまうためです。
CLAUDE_CODE_RESUME_PROMPTは、この手順4で-p --resumeを実行するときにClaudeへ送られる継続メッセージを差し替えます。deferされたセッションにはタイムアウトや再試行回数の制限がなく、cleanupPeriodDays設定(既定30日)によるクリーンアップまでディスク上に残り続けます。回答がまだ揃っていなければ、フックはもう一度"defer"を返してよく、ループを抜けるタイミングは呼び出し側のアプリケーションが判断します。
保留していたツールが再開時にもう使えなくなっていることもあります。ツールを提供していたMCPサーバーが再開したセッションに接続されていない場合、フックが発火する前にプロセスはstop_reason: "tool_deferred_unavailable"かつis_error: trueで終了します。この場合もdeferred_tool_useの情報は結果に含まれるため、呼び出し側はどのツールが失われたかを特定できます。deferされたセッションをplanモードのまま再開したいときは、--resumeと一緒に--permission-prompt-toolを渡す必要があります(v2.1.246以降)。
MAX_AGE_MSで再開を諦めるまでの経過時間を決める
CLAUDE_CODE_RESUME_INTERRUPTED_TURN_MAX_AGE_MSは、セッションがターンの途中で終わったとき、transcriptの最後のメッセージがどれだけ古ければ自動再開を諦めるかをミリ秒単位で指定します。この上限を超えていると、Claude CodeはCLAUDE_CODE_RESUME_INTERRUPTED_TURNによる自動再開と、そのときのCLAUDE_CODE_RESUME_PROMPT継続メッセージをスキップし、セッションはアイドル状態で立ち上がって明示的な指示待ちになります。この変数はv2.1.211以降で利用できます。
設定値ごとの挙動は次のとおりです。
| 設定値 | 挙動 |
|---|---|
未設定または0 | 挙動上限なし。ただし直前のリクエストがAPIエラーで失敗したターンに限り、そのエラーから6時間未満のときだけ再開する |
| 正の数値 | 挙動APIエラー由来のターンも含め、すべてのターンにこのミリ秒数の上限を適用する |
| 負の値または数値でない値 | 挙動1時間の上限を適用する |
Claude Codeがagent viewのクラッシュしたセッションを再起動するときは、対話セッションから会話を引き継いだ場合に限り、この変数を自前で1時間に設定します。長時間動かすエージェントのスポーンスクリプト側でこの変数を明示しておけば、古いtranscriptに対する再起動が、期限切れのプロンプトをそのまま再実行してしまう事故を防げます。
export CLAUDE_CODE_RESUME_INTERRUPTED_TURN_MAX_AGE_MS=3600000上の例は1時間(3,600,000ミリ秒)を上限にする設定です。数値変数は3_600_000のような桁区切り表記や3.6e6のような指数表記でも受け付けます。ただしv2.1.211より前は桁区切り・指数表記の解釈にバグがあり、1e6が意図せず極端に小さい値として扱われることがありました。
SDKやスポーンスクリプトでの使いどころ
CLAUDE_CODE_RESUME_INTERRUPTED_TURNはSDKモードでの利用を想定した機能です。Agent SDKを使ったアプリがClaude Codeをサブプロセスとして起動し、ネットワーク断やプロセス再起動でターンが中断されたとき、この変数を立てておけば呼び出し側は同じプロンプトを再送する処理を持たずに済みます。
一方で、長時間放置されたセッションを無条件に再開すると、数日前の古い指示が今のコンテキストに対して実行される事故につながります。MAX_AGE_MSはこの事故を防ぐための安全弁で、既定(未設定)のままだとAPIエラー由来のケースにしか6時間の上限が効かないことに注意が必要です。定常的に動かすエージェント基盤では、明示的に数値を設定しておくのが安全です。予算到達やアイドル状態からの再開を含めたエージェント運用の実装パターンは、Managed Agentsの予算到達・アイドル再開の記事で扱っています。
対話セッションのインタラクティブな/resumeとは別物である点にも注意します。利用上限のリセット後にセッションを自動で再開したい場合はClaude Codeの利用上限リセット後の自動再開設定が扱う仕組みで、CLAUDE_CODE_RESUME_INTERRUPTED_TURNとは制御対象が異なります。
たとえば監視プロセスが数秒おきにヘルスチェックを行い、応答がなければclaude -p --resumeで再起動するような構成では、MAX_AGE_MSを短めに設定しておくことが重要です。ヘルスチェックの間隔が短くても、ネットワーク障害でプロセスが長時間放置されるケースはあり、放置後に自動再開すると数時間前の古い指示がそのまま実行されてしまいます。MAX_AGE_MSをヘルスチェックの許容遅延に合わせた値(たとえば数分〜数十分のミリ秒数)にしておけば、古すぎるセッションはアイドル状態で起動し、監視プロセス側の判断に委ねられます。
settings.jsonでの固定と反映タイミング
シェルのexportはclaudeの起動時に読み込まれる、そのターミナルセッションだけの設定です。変更を反映するには再起動が必要です。チーム全員に同じ挙動を強制したい場合は、.claude/settings.jsonのenvキーに書きます。
{
"env": {
"CLAUDE_CODE_RESUME_INTERRUPTED_TURN": "1",
"CLAUDE_CODE_RESUME_INTERRUPTED_TURN_MAX_AGE_MS": "1800000"
}
}同じ変数をシェルと設定ファイルの両方で指定した場合は、設定ファイルの値が優先されます。実行中のセッションでも、ファイルを保存した時点で新しい値が反映されます。ただし例外があり、OpenTelemetryのように起動時に一度だけ変数を読む機能は、ファイルを書き換えても再起動するまで古い値を使い続けます。
設定ファイル側では変数を「unset」にはできない点にも注意します。シェルのプロファイルが勝手に設定してしまうCLAUDE_CODE_USE_VERTEXのような変数を打ち消したいときは、envブロックで空文字列("")を指定すると、Claude Codeはそれを未設定として扱います。
複数の設定ファイルが同じ変数を持つ場合は、管理者が配布するmanaged settingsがユーザー設定・プロジェクト設定より優先されます。CLAUDE_CONFIG_DIRのように、プロジェクト設定やローカル設定からは変更できない変数もあります。
よくあるつまずき
0を設定したのに再開が止まらない: v2.1.221より前のバージョンでは非対話モードでCLAUDE_CODE_RESUME_INTERRUPTED_TURN=0が無視され、自動再開が発動し続けます。古いバージョンで無効化したいときは変数自体をunsetしますMAX_AGE_MSを設定したのにAPIエラー由来のターンだけ再開してしまう: 未設定または0のままだと、APIエラーで失敗したターンに限り6時間の猶予が別枠で効きます。すべてのターンに同じ上限をかけたいなら、0ではなく具体的な正の数値を設定します- 桁区切り表記が意図と違う値になる: v2.1.211より前は
1e6のような指数表記や64_000のような桁区切り表記の解釈にバグがあり、意図せず極端に小さい値になることがありました
まとめ
CLAUDE_CODE_RESUME_INTERRUPTED_TURNで自動再開を有効にした上で、継続メッセージを変えたいならCLAUDE_CODE_RESUME_PROMPT、再開を諦めるまでの経過時間を変えたいならCLAUDE_CODE_RESUME_INTERRUPTED_TURN_MAX_AGE_MSを設定します。CLAUDE_CODE_MAX_TURNSのようにセッションの動作を環境変数で締めるほかの設定と併用すると、長時間稼働するエージェントの挙動を細かく制御できます。