Claude Media
CLAUDE_CODE_DISABLE_BG_EXIT_HANDOFFでバックグラウンド引き継ぎを止める

CLAUDE_CODE_DISABLE_BG_EXIT_HANDOFFでバックグラウンド引き継ぎを止める

supervisorがバックグラウンドセッションのプロセスを再起動するとき、実行中のシェルコマンドやサブエージェントを次プロセスへ渡さず止める環境変数の挙動と設定方法。

CLAUDE_CODE_DISABLE_BG_EXIT_HANDOFFとは

CLAUDE_CODE_DISABLE_BG_EXIT_HANDOFFは、Claude Codeのバックグラウンドセッションを管理するsupervisorが停止・再起動・更新するときの引き継ぎを止める環境変数です。1を設定すると、実行中のシェルコマンド・動的ワークフロー・(v2.1.198以降は)サブエージェントが、そのセッションの次のプロセスへ引き継がれずに止まります。Claude Code v2.1.196以降が必要です。

デフォルトの挙動はこの逆で、プロセスが止まっても作業が次のプロセスに引き継がれ、続きが動きます。この引き継ぎはv2.1.196で改善された機能で、長時間実行のコマンドやワークフローが、プロセスの停止・再起動・更新のあとも処理が続くようになりました。Windowsではバックグラウンドシェルがkillされる代わりにハンドオフされる、という変更も同じリリースに含まれています。

supervisorがプロセスを止める・再起動する4つの場面

agent viewに載っているセッションはすべてバックグラウンドセッション扱いで、supervisorという常駐サービスがそれぞれを個別のClaude Codeプロセスとして走らせています。プロセスの扱いは、セッションの状態で次のように変わります。

セッションの状態supervisorの動作
作業中・許可プロンプト等で一時停止中・アタッチ中supervisorの動作プロセスは動き続ける
完了または返信待ちで、アタッチなしのまま約1時間supervisorの動作プロセスを止めてリソースを解放する(会話はディスクに残る)
supervisor稼働中に予期せず終了したsupervisorの動作プロセスを再起動する
自動アップデート後supervisorの動作supervisor自身を新バージョンへ再起動し、アイドル中のセッションを裏で移す

このうち「予期せず終了した」場合と「自動アップデート後」の2つで、プロセスが差し替わります。差し替え時にセッションが実行していたバックグラウンドシェルコマンド・動的ワークフロー・バックグラウンドサブエージェントは、既定では次のプロセスへ引き継がれます。稼働中のmonitorや、サブエージェントが起動したシェルコマンドはプロセスと一緒に止まるので対象外です。

CLAUDE_CODE_DISABLE_BG_EXIT_HANDOFF=1を設定すると、この引き継ぎ自体を止め、プロセスの入れ替わりと一緒にすべて停止させます。

設定方法

シェルでのエクスポート、またはsettings.jsonのenvキーで設定します。

export CLAUDE_CODE_DISABLE_BG_EXIT_HANDOFF=1

settings.jsonに書く場合は次のようになります。

{
  "env": {
    "CLAUDE_CODE_DISABLE_BG_EXIT_HANDOFF": "1"
  }
}

claude daemon stop --anyでsupervisorそのものを止めたときも同じ経路を通ります。このコマンドはsupervisorプロセスとそこがホストするバックグラウンドセッションを停止するもので、--keep-workersを付ければバックグラウンドセッションだけ動かし続け、次にclaude agentsかclaude --bgを実行したときに新しいsupervisorがそれらへ再接続します。CLAUDE_CODE_DISABLE_BG_EXIT_HANDOFF=1のもとでは、--keep-workersを付けない通常のdaemon stopで、実行中のシェルコマンド・ワークフロー・サブエージェントがそこで止まります。

CLAUDE_DISABLE_ADOPTとの範囲の違い

似た名前の環境変数にCLAUDE_DISABLE_ADOPTがあります。両者は「引き継ぎを止める」という効果は共通していますが、対象にするタイミングが異なります。

環境変数対象になる場面対象にならない場面
CLAUDE_CODE_DISABLE_BG_EXIT_HANDOFF対象になる場面supervisorがプロセスを停止・再起動・更新するとき対象にならない場面←や/backgroundでセッション自身をバックグラウンドへ送るとき(そちらは引き続き引き継がれる)
CLAUDE_DISABLE_ADOPT対象になる場面←や/backgroundでセッションをバックグラウンドへ送るとき、およびsupervisorによるプロセス入れ替え時(両方)対象にならない場面対象外なし

/background(エイリアス/bg)でセッションをバックグラウンドへ送ると、実行中のバックグラウンドシェルコマンド・バックグラウンドサブエージェント・動的ワークフロー・/loopで作ったスケジュールタスク・Artifactコメントへの自動返信が、新しいプロセスへそのまま移って動き続けます。CLAUDE_DISABLE_ADOPT=1を設定すると、この移行の前に確認を挟み、確認すると引き継がずに止めます。

一方でCLAUDE_CODE_DISABLE_BG_EXIT_HANDOFFが対象にするのは、supervisorがセッションのプロセスを裏で入れ替えるタイミングだけです。env-vars.mdは両者の関係を「CLAUDE_DISABLE_ADOPTはその両方を止める」と説明しており、CLAUDE_DISABLE_ADOPT=1を設定すれば、supervisorによる入れ替え時の引き継ぎと、手動でバックグラウンドへ送るときの引き継ぎの両方が止まります。逆にCLAUDE_CODE_DISABLE_BG_EXIT_HANDOFFだけを設定した場合、/backgroundや←で自分から送ったときの引き継ぎには影響しません。

Windowsのシェルコマンドは既定でも扱いが違う

Windows環境では、バックグラウンドで動くPowerShellツールのコマンドが既定でcmd.exeランチャー経由で起動し、セッションの次のプロセスへ引き継がれる仕組みになっています。これはv2.1.196で入った改善で、それ以前はWindowsのバックグラウンドシェルがプロセスの入れ替わりでkillされていました。

CLAUDE_CODE_DISABLE_WINDOWS_SHELL_LAUNCHER(v2.1.269以降)を設定すると、PowerShellツールのコマンドをcmd.exeランチャーを介さず直接起動するようになり、その代わりにセッションのプロセスが終了するとバックグラウンドのPowerShellコマンドも一緒に止まります。Bashコマンドはこの変数の影響を受けません。CLAUDE_CODE_DISABLE_BG_EXIT_HANDOFFが引き継ぎそのものを止めるのに対し、こちらはWindowsでの引き継ぎ手段(ランチャー経由かどうか)を切り替える変数で、対象も効果も別物です。両方を設定した場合、Windowsのバックグラウンドシェルはいずれにせよ次プロセスへは渡らなくなります。

サブエージェントの引き継ぎには条件がある

v2.1.198以降、バックグラウンドサブエージェントも既定の引き継ぎ対象に加わりました。ただし公式ドキュメントは「サブエージェントは、それが起動したものすべてと一緒に移動し、その作業全部が移動できるときだけ引き継がれる」と説明しています。サブエージェントが起動したシェルコマンドやmonitorのうち、プロセスをまたいで継続できないものがあると、サブエージェント自体の引き継ぎも成立しません。

/backgroundでセッション自身を手動でバックグラウンドへ送るときも似た制約があり、動的ワークフローがまだサブエージェントを実行中だと、Claude Codeは「いくつのサブエージェントが再スタートするか」を示す確認ダイアログを出します。ここで続行を選ぶと、実行中だったサブエージェントは最初からやり直しになり、それまで消費したトークンも再度消費されます。

supervisorの状態を確認する

CLAUDE_CODE_DISABLE_BG_EXIT_HANDOFFを設定したかどうかにかかわらず、supervisorが今どう動いているかはclaude daemon statusで確認できます。

claude daemon status

このコマンドはsupervisorに到達できるか、そのプロセスIDとバージョン、ソケットディレクトリ、稼働中のバックグラウンドセッション数を返します。実行中のclaudeコマンドとsupervisorのバージョンが食い違っているとき(アップデート後にsupervisorがまだ再起動していない場合など)も警告してくれるので、CLAUDE_CODE_DISABLE_BG_EXIT_HANDOFF=1を設定した環境でバックグラウンド処理が想定どおり止まったか確かめる起点になります。

各バックグラウンドセッションの状態は~/.claude/jobs/<id>/state.jsonに保存されますが、公式ドキュメントはこのファイルを直接パースせずclaude agents --jsonで読むことを推奨しています。セッションを特定できずにdaemon statusの結果を読み違えるケースは、セッションを見分ける方法を先に押さえておくと避けやすくなります。

どういうときに設定するか

この環境変数を設定する理由になり得るのは、次のような場面です。

  • バックグラウンドサブエージェントが影響範囲の広い操作(デプロイ・外部APIへの書き込みなど)を実行しており、supervisorの再起動をまたいで同じ操作を継続させたくない場合。既定の引き継ぎでは、supervisorが予期せず再起動したときにそのサブエージェントの作業が次のプロセスでも続きます
  • 自動アップデートのタイミングで、進行中のバックグラウンド処理を明示的に区切りたい運用。自動アップデートでsupervisorが新バージョンへ再起動しセッションのプロセスが差し替わるとき、既定では実行中のシェルコマンド・ワークフロー・サブエージェントが次のプロセスへ引き継がれますが、この変数を設定していればそこで止まります
  • supervisorのプロセス管理の挙動を検証・デバッグしたい場合。引き継ぎを無効化すれば、プロセスの入れ替わりでどの処理が本来止まるはずだったかを切り分けられます

逆に、長時間実行するワークフローやシェルコマンドをsupervisorの再起動・更新をまたいで完走させたいだけなら、v2.1.196以降のデフォルト挙動(引き継ぎあり)のままにしておく方が適しています。この変数はその既定の挙動を明示的にオプトアウトするためのものです。

引き継ぎを止めた後、セッションはどう表示されるか

引き継ぎを止めてプロセスがそこで停止すると、agent view上のセッション表示は、最後に進捗があってからの経過時間で変わります。48時間以内ならfailedと表示され、その行にアタッチするか返信すると、止まったところから再開します。48時間を超えている場合はstoppedと表示され、ended while the background service was offという案内が添えられます。同じ行でEnterをもう一度押すと保存済みの会話を再開でき、返信やclaude attach <id>でも同じように再開できます。マシンをスリープさせただけではセッションは止まらず、supervisorが復帰時に自動で再接続するため、この表示分岐が出るのはあくまでプロセスが実際に止まったときだけです。stoppedのまま長期間放置したセッションは、設定した保存期間(transcript cleanup)を過ぎると保存済みの会話ごと削除され、行を開いても「再開する会話がない」と表示されるだけになります。引き継ぎを止める運用にするなら、止まったセッションをいつまでに再開するか・削除するかも合わせて決めておくと安全です。

まとめ

CLAUDE_CODE_DISABLE_BG_EXIT_HANDOFF=1は、supervisorがバックグラウンドセッションのプロセスを停止・再起動・更新する場面に限定して、実行中のシェルコマンド・ワークフロー・(v2.1.198以降の)サブエージェントの引き継ぎを止める設定です。←や/backgroundで自分からセッションをバックグラウンドへ送る場合の引き継ぎには影響しません。両方の経路をまとめて止めたいときはCLAUDE_DISABLE_ADOPTを使います。Claude Code v2.1.196以降で利用でき、exportかsettings.jsonのenvキーで設定します。

この記事を共有:XはてブLinkedIn