「CLAUDE_CODE_PROCESS_WRAPPER」の起動エラー — Claude Code企業ランチャー
企業ランチャーを噛ませるCLAUDE_CODE_PROCESS_WRAPPERが原因でClaude Codeが起動しないときの、エラー文言別の切り分け方と契約違反の見つけ方をまとめます。
CLAUDE_CODE_PROCESS_WRAPPERは、企業が求める必須ランチャーを経由してClaude Codeの各プロセスを起動する仕組みです。値が使えないとき、Claude Codeはラップせずに起動するのではなく、そのプロセスの起動そのものを拒否します。エラーメッセージは変数名で始まり理由を続ける形式で、原因はほぼ「ランチャースクリプトが契約を満たしていない」の一点に絞られます。
CLAUDE_CODE_PROCESS_WRAPPERが対象にする範囲
企業によっては、ワークステーション上のすべてのプロセスを必須ランチャー経由で起動させ、サンドボックスやネットワーク制御、認証情報の注入をそこで適用させる方針があります。CLAUDE_CODE_PROCESS_WRAPPERは、Claude Codeが自分のバイナリから起動するプロセス全てをこのランチャー経由にします。
対象になるのは、バックグラウンドサービス(エージェントビューがホストするセッション)、アップデート後の再起動、Remote Controlのワーカープロセス(v2.1.210以降)、agent teamsがtmux/iTerm2で開く分割ペインのセッション(v2.1.210以降)です。claudeコマンドをPATH上でラップするタイプのランチャーは、これらのプロセスに届きません。自分のバイナリの直接パスから起動するため、claudeという名前の解決を経由しないからです。
対象外のプロセスもあります。設定前から動いているインストール済みバックグラウンドサービス(launchd/systemdが起動)、ターミナルで自分で起動したセッション、claude-cli://ディープリンクが開く最初のプロセス、--worktreeと--tmuxの組み合わせが開く再起動、Claude in Chromeのネイティブメッセージングホストです。これらをカバーするには、PATH上のclaudeより手前のディレクトリに、実バイナリを自分のランチャー経由で呼ぶスクリプトを置く方法があります。
Windowsでは変数自体が無視されます。ランチャーの契約はexecを前提にしており、Windowsはこれをサポートしないためです。Windows機に変数を設定しても全プロセスがラップされずに動き続け、デバッグログに警告が出るだけです。ロールアウト計画では、Windows機をラップ対象外として数える必要があります。
エラーメッセージ別の切り分け方
設定ミスの種類によって、エラーの出方が変わります。
値そのものが使えない場合は、変数名で始まり理由を続けるメッセージが出ます。
CLAUDE_CODE_PROCESS_WRAPPER: launcher `/opt/corp/launcher` is not an executable regular fileランチャーが起動はするが自分自身をexecで置き換えず終了してしまう場合は、開始しようとしていたセッションが失敗し、エージェントビューの行がランチャー名を含む「must exec, not daemonize」というメッセージを報告します。ランチャーが残した子プロセスは、バックグラウンドサービスが後から回収します。
セッションがバックグラウンドサービスに到達できない場合は、ランチャーの問題がCouldn't reach the background service (...)の理由として内側に表示されます。
processWrapper設定・VS Code拡張の設定との使い分け
同じ役割を持つ設定が3つあり、対象範囲とバージョン要件が違います。
| 設定 | 対象 | 必要バージョン | 設定できる場所 |
|---|---|---|---|
CLAUDE_CODE_PROCESS_WRAPPER(環境変数) | 対象Claude Code自身が起動するプロセス全般 | 必要バージョンv2.1.208以降 | 設定できる場所envブロック(ユーザー設定 / managed settings) |
processWrapper(設定キー) | 対象同上。環境変数と同じ値を名前付きキーとして渡す | 必要バージョンv2.1.210以降 | 設定できる場所ユーザー設定 / managed settings / --settingsファイル |
claudeProcessWrapper(VS Code拡張) | 対象拡張機能がバンドルするバイナリの起動方法そのもの | 必要バージョン拡張機能側の設定 | 設定できる場所VS Code拡張の設定 |
CLAUDE_CODE_PROCESS_WRAPPERとprocessWrapperは両方設定されていると環境変数側が優先されます。プロジェクト設定・ローカル設定ではどちらも設定できません。リポジトリにコミットされたファイルが、マシン上の全プロセスの前にバイナリを割り込ませられてはならないためで、.claude/settings.jsonや.claude/settings.local.jsonに書いても無視され、デバッグログに警告が残ります。
VS CodeのclaudeProcessWrapperは名前が似ていますが、対象が別物です。拡張機能がバンドルするclaudeバイナリの起動方法を指すもので、企業ランチャーの契約とは無関係です。ラップされたセットアップでは、拡張が設定と組み込みデフォルトの手順をスキップするため、会話はManualモードで始まります。
ランチャースクリプトが満たすべき契約
ランチャーが起動できないとき、Claude Codeはラップなしで起動するのではなく、そのプロセスの起動を拒否します。契約は次の通りです。
- 必ず
exec "$@"で終わる。子プロセスをforkして自分は終了するランチャーは、バックグラウンドサービスが追跡できない孤立プロセスを残します - 引数を並べ替えたり吸収したり先頭に追加したりしない。最初の引数がClaude Codeのバイナリで、それ以降が丸ごとargvです
- 継承した環境変数をすべて
execに渡す。認証情報の注入など変数を足すのは構いませんが、継承した変数を落としてはいけません。セッションごとの認証トークンやモデル選択、CLAUDE_CODE_PROCESS_WRAPPER自体もこの継承環境に乗っているため、許可リストで環境を再構築するランチャーはそれが起動するセッションを壊します - 毎回の起動から3秒ほどで
execに到達する。バックグラウンドの初回ディスパッチはランチャーを最初の出力バイト前に2回連続で実行するため、シングルサインオンのような重い処理は遅延させるかキャッシュから読みます - 自分自身の内側から呼ばれることに耐える。Claude Codeはネストした自己再起動のすべてにランチャーを適用するため、排他リソースを取得するランチャーはすでに保持していることを検知する必要があります
- Claude Codeが起動する前に端末へ書き込まない。
execより前に出力した内容は、セッションが初期化前に落ちた場合クラッシュの原因として報告されます
値のフォーマットと反映手順
値はランチャーの絶対パスが基本で、/opt/corp/launcherのような形式です。ランチャー自身に引数を渡したいときはパスの後に続けて書きます。空白がトークンを区切り、二重引用符で空白を含むトークンをまとめられます。[で始まる値はJSON文字列配列として読まれ、["/opt/corp/launcher", "--profile", "cc"]のような書き方もできます。シェル構文は使えません。変数展開やグロブは効かず、;・|・&・$(のようなクォートなしの演算子は設定エラーとして拒否されます。
{
"env": {
"CLAUDE_CODE_PROCESS_WRAPPER": "/opt/corp/launcher"
}
}設定を変えたら、実行中のバックグラウンドサービスと開いているclaudeセッションを再起動しないと反映されません。両方とも起動時に一度だけ変数を読むためです。
claude daemon stop --any次にclaude agentsのようにサービスを必要とするコマンドを実行すると、ラップされたサービスが新しく立ち上がります。反映されたかどうかは/statusのSelf-exec欄で確認でき、実行中のバックグラウンドサービスが設定と一致しないときはここに警告が出ます。
CLAUDE_CODE_SHELL_PREFIXとの違い
似た名前のCLAUDE_CODE_SHELL_PREFIXと混同しないようにします。CLAUDE_CODE_PROCESS_WRAPPERはClaude Code自身のプロセスをラップし、コマンドを別々のargvトークンとしてランチャーのexecに渡します。CLAUDE_CODE_SHELL_PREFIXはBashツール呼び出し・hooks・stdio型MCPサーバーの起動コマンドなど、Claudeが代わりに実行するシェルコマンドをラップし、それぞれを$1の中に1つのシェルクォート済み文字列として渡します。片方向けに書いたランチャーは、もう片方としては動きません。
よくあるつまずき
- 以前
~/.local/bin/claudeのシンボリックリンクを自作ランチャーで置き換えていた場合は、同じ変更で元のシンボリックリンクに戻します。置き換えたままだと最初のラップされたセッションが2つのランチャーを同時に経由して起動し、/doctorが外部管理状態として報告し続けます - managed settingsの値は、ユーザー設定にもシェルのexportにも優先します。複数のソースで設定していると、ユーザーが別のランチャーを指すよう変更できなくなります
- Windowsでは変数が無視されるため、ラップ必須のポリシーを敷いている組織は、Windows機だけ別の統制手段を用意する必要があります
- 設定前から動いているインストール済みサービスは対象外のままです。
/statusとclaude daemon statusが、稼働中のサービスと設定の不一致を警告し続けている場合は、サービスの再起動を忘れています
よくある質問
CLAUDE_CODE_PROCESS_WRAPPERはBashツールが実行するコマンドもラップしますか
しません。Claudeが代わりに実行するシェルコマンドをラップするのはCLAUDE_CODE_SHELL_PREFIXで、別の仕組みです。CLAUDE_CODE_PROCESS_WRAPPERはClaude Code自身のプロセス起動だけが対象です。
プロジェクトの.claude/settings.jsonにCLAUDE_CODE_PROCESS_WRAPPERを書けば全員に配れますか
書けません。プロジェクト設定・ローカル設定はどちらも無視され、デバッグログに警告が残るだけです。組織全体に配るにはmanaged settingsを使います。
設定を反映したのにまだラップされていないプロセスが残るのはなぜですか
設定前から動いているインストール済みバックグラウンドサービスは、launchdやsystemdが起動したままなので対象外です。claude daemon stop --anyで止め、次回の起動でラップ済みのサービスに切り替えます。
まとめ
CLAUDE_CODE_PROCESS_WRAPPERまわりのエラーは、ほとんどがランチャースクリプト側の契約違反です。exec "$@"で終わっているか、環境変数を落としていないか、3秒以内に到達しているかを順に確認します。値の形式はJSON配列か引用符付きのトークン列で、シェル構文は使えません。設定変更後はclaude daemon stop --anyと/statusでの確認を忘れずに行います。企業向けのネットワーク設定とあわせて導入するケースが多いため、両方の手順を一度に整理しておくと運用が安定します。