CLAUDE_CODE_USER_DIALOG_TIMEOUT_MSとは — 転送ダイアログの期限を決める変数
CLAUDE_CODE_USER_DIALOG_TIMEOUT_MSがどのダイアログの期限を決め、dialogExpiryやaskUserQuestionTimeoutとどう分担するかを、v2.1.290の単位指定の修正も含めて解説します。
CLAUDE_CODE_USER_DIALOG_TIMEOUT_MSは、Claude Codeが遠隔のクライアントへ転送したダイアログに回答期限を設ける環境変数です。単位はミリ秒で、0か負の値を入れると期限がなくなります。
名前に「USER_DIALOG」とあるため、承認プロンプトや質問の待ち時間も決めると読まれがちです。実際は権限プロンプトとAskUserQuestionの質問は対象外で、どちらも回答するまで開いたままです。
期限が決まるダイアログは3種類
この変数が期限を与える対象は、次の3種類です。
この変数が期限を決める対象
転送されたダイアログ
Remote ControlやSDKホストなど、接続先のクライアントへ転送されるダイアログです。
保留中のクロスセッションメッセージ
別セッションから届き、承認待ちで保留されたメッセージの承認ダイアログです。
Fableの使用量クレジット同意
v2.1.236以降で対象になる、セッション途中に出る同意プロンプトです。
Remote Controlの制限事項の例として、安全性の拒否のあとに出るモデル選択プロンプトが挙げられています。転送先で誰も答えなければ、期限後にダイアログを閉じ、そのダイアログの「何もしない」既定の動作で続行します。
SDKホストの場合、ダイアログを出すかどうかはホストするアプリケーション次第です。出た場合に誰も答えなければ、同じdialogExpiryの期限で、Claude Codeはリクエストを送らずにターンを終えます。
一方、権限プロンプトとAskUserQuestionはこの期限の外です。Remote Controlの解説でも、これらは回答するまで開いたままと書かれています。
設定の置き場所は2つ、強さは変数が上
同じ期限は、設定キーのdialogExpiryでも決められます。
| 手段 | 形式 | 既定値 | 効く範囲 |
|---|---|---|---|
dialogExpiry(設定) | 形式"60s" / "5m" / "10m" / "never" | 既定値"5m" | 効く範囲恒常 |
CLAUDE_CODE_USER_DIALOG_TIMEOUT_MS(環境変数) | 形式ミリ秒の数値 | 既定値なし | 効く範囲1セッション |
環境変数は、そのセッションに限ってdialogExpiryより優先されます。設定キーはdialogExpiryの公式説明にあるとおり、v2.1.224以降で使えます。dialogExpiryはneverで期限を無効にし、環境変数は0か負の値で無効にします。無効化の書き方が違う点に注意が必要です。
{
"dialogExpiry": "10m"
}セッション単位で変えたいときは、起動時に環境変数を付けます。10分なら600000です。
CLAUDE_CODE_USER_DIALOG_TIMEOUT_MS=600000 claude単位付きの値は使わない
CLAUDE_CODE_USER_DIALOG_TIMEOUT_MS=5mのように書くと、5mが5ミリ秒と読まれ、転送ダイアログがすぐキャンセルされる不具合がありました。v2.1.290で直り、単位付きの値はdialogExpiryの設定に戻る動作になっています。
変数の名前が_MSで終わる以上、書くのはミリ秒の数値だけです。5mは設定キー側の書式なので、混ぜないほうが安全です。
# 良い例: ミリ秒の数値
CLAUDE_CODE_USER_DIALOG_TIMEOUT_MS=300000
# 避ける例: 設定キーの書式を変数に入れる
CLAUDE_CODE_USER_DIALOG_TIMEOUT_MS=5m質問の自動継続はaskUserQuestionTimeoutが担当
AskUserQuestionの質問を、離席中に自動で先へ進めたい場合は別の経路です。担当はaskUserQuestionTimeout設定で、値は"60s"・"5m"・"10m"・"never"、既定は"never"です。1セッションだけ上書きする環境変数はCLAUDE_AFK_TIMEOUT_MSになります。
質問の側は、期限の最後の20秒にカウントダウンが表示され、何かキーを押すとタイマーが戻ります。端末のウィンドウにフォーカスがある間は、カウントダウンも進みません。カウントダウンを出し始める位置はCLAUDE_AFK_COUNTDOWN_MSで変えられ、既定は20000(20秒)です。自動継続のタイムアウトを超える値にはならず、自動継続がオフなら効果がありません。
CLAUDE_AFK_TIMEOUT_MSには癖があります。設定するとaskUserQuestionTimeoutが未設定やneverでも自動継続がオンになり、0を入れると無効ではなくダイアログがすぐ閉じます。デモや自動テスト向けの上書きで、v2.1.200より前は60秒の自動継続が既定でオンでした。CLAUDE_CODE_USER_DIALOG_TIMEOUT_MSの0は期限なしなので、同じ0でも正反対の動作になります。
質問の側は、期限が来るとダイアログが閉じて、選択済みの選択肢を送信し、離席しているかもしれないとClaudeに伝えます。ダイアログが開いたままになる場面もあります。バックグラウンドセッション、スクリーンリーダーモード、Remote Control接続中は、タイマーが始まりません。AskUserQuestionの無応答の記事に詳しい切り分けがあります。
| やりたいこと | 使う手段 |
|---|---|
| 転送ダイアログの期限を変える | 使う手段dialogExpiry / CLAUDE_CODE_USER_DIALOG_TIMEOUT_MS |
| 質問を離席中に自動継続する | 使う手段askUserQuestionTimeout / CLAUDE_AFK_TIMEOUT_MS |
| 権限プロンプトを自動で通す | 使う手段期限ではなく権限ルールやフック |
権限プロンプトは、idle時間では自動解決されません。無人運用で通したい承認は、期限の延長ではなくルールで事前に許可する設計になります。
クロスセッションの保留メッセージの期限
別セッションから届いたメッセージを、受信側がbypassPermissionsで動いているなどの理由で保留すると、承認ダイアログが開きます。期限までに答えないと、ダイアログは閉じてメッセージは破棄されます。既定は5分です。承認すると、そのメッセージ1通だけがClaudeに届きます。拒否するかダイアログを閉じると、メッセージは破棄されます。
-pで動かす非対話セッションは、このダイアログを表示できません。保留したメッセージは同じ期限の間だけ保持し、期限を過ぎると破棄して、届く相手には期限切れとして知らせます。期限内に権限モードや設定が変われば、そのとき配送されます。
dialogExpiryを"never"にすると、既定の判断で保留されたメッセージは、セッションが終わるまで残ります。crossSessionInboundで明示的にholdにした保留は、そもそも期限切れになりません。この変数の扱いは、送受信の仕組みを扱うSendMessageの記事と合わせて読むと全体がつかめます。
保留できるのは最大100通で、超えると古いものから破棄されます。
crossSessionInboundの値(accept / hold / refuse)が決まっていれば、この判断は走りません。管理設定、--settingsフラグ、ユーザー設定の順に最初に見つかった値が使われ、refuseがholdより、holdがacceptより厳しい扱いです。プロジェクトやローカルの値は、それより厳しいときだけ効きます。VS Code拡張とDesktopアプリのセッションは承認ダイアログを出せないため、-pと同じく同じ期限だけ保留します。
なお、バックグラウンドセッションにターミナルがつながっていない間は、期限を過ぎてもダイアログを開いたままにします。接続したあと、丸1回分の期限を超えて答えがなければ、閉じてメッセージを破棄します。
Fableの同意プロンプトとの関係
v2.1.236以降は、Fableの使用量クレジット同意プロンプトにも同じ期限が使われます。Remote Control接続中、バックグラウンドセッション、エージェントチームのチームメイト、Agent SDKで他アプリがホストするセッションが対象です。
このプロンプトは、組織課金のEnterpriseプランのメンバーには出ません。表示された場合、閉じるとモデルの選択は変わらず、/modelで選んだ直後なら現在のモデルのまま、セッション途中ならターンが既定モデルで続きます。期限までに誰も答えないと、リクエストを送らずにターンを終え、トランスクリプトに通知が残ります。表示は「the prompt to confirm went unanswered」を含む文面です。
- Remote Control接続中やチームメイトのセッションでは、ターミナルで何かキーを押すと期限が取り消され、回答を待つ状態になる
- バックグラウンドセッションでは、期限内に回答する必要がある
- Remote Controlでは、このプロンプトは手元の端末に転送されない
同意の仕組み自体は使用量クレジットが求められる原因の記事が詳しく、期限を延ばしたいときはこの変数が選択肢になります。
「prompt to confirm went unanswered」が出たとき
期限切れでFableのターンが終わると、次のどちらかの文面が出ます。
Fable limit reached · continuing on Fable 5.1 uses usage credits, and the prompt to confirm went unanswered — nothing was sent · answer it where this session is running, or /model to change
Fable 5.1 now uses usage credits · the prompt to confirm went unanswered — nothing was sent · answer it where this session is running, or /model to changeモデル名はセッションのFableに合わせて変わり、Fable 5ならFable 5と出ます。リクエストは送られておらず、モデルの選択も変わりません。対処は3つです。
- セッションが動いている場所(端末、またはホストするアプリ)でもう一度プロンプトを送り、再表示された同意に答える。バックグラウンドセッションなら、先にエージェントビューから接続する
/modelで使用量クレジットを消費しないモデルに切り替えるdialogExpiryを長い値か"never"にして、答える時間を確保する
Remote Controlのクライアントから再送しても、クライアントにはプロンプトが出ないため、同じ文面がまた出ます。v2.1.236より前は、Remote Control接続中は60秒待ってから既定モデルで続行していました。
プロジェクト設定には書けない
環境変数をsettingsのenvブロックで設定する場合、プロジェクト設定とローカル設定では無視されます。CLAUDE_CODE_USER_DIALOG_TIMEOUT_MS・CLAUDE_AFK_TIMEOUT_MS・CLAUDE_AFK_COUNTDOWN_MSは、ダイアログの期限を決める変数としてまとめて無視の対象です。v2.1.290より前は、プロジェクトやローカルの設定からも決められました。
共有リポジトリの.claude/settings.jsonに書いて全員の期限を揃える使い方は、v2.1.290以降はできません。揃えたいなら、ユーザー設定か管理者設定のdialogExpiryを使います。
まとめ
転送ダイアログ・保留メッセージ・Fableの同意プロンプトの期限は、dialogExpiryが恒常、CLAUDE_CODE_USER_DIALOG_TIMEOUT_MSが1セッションの上書きです。質問の自動継続は別系統で、権限プロンプトには期限そのものがありません。
無人のワーカーが承認待ちで止まって困るなら、まず対象のダイアログがどの系統に属するかを見ます。系統が分かれば、触る設定は1つに絞れます。