Claude Codeのworktree isolation checksで拒否される原因と直し方
worktreeで隔離したClaude Codeがコマンドを「This session is isolated in the worktree」で拒否する3つの理由と、書き直し方、メインチェックアウトを操作したいときの手順を解説します。
worktreeで隔離したClaude Codeのセッションでコマンドを流すと、This session is isolated in the worktree /path/to/worktree, but this command … で始まる拒否メッセージが返ることがあります。これは壊れたのではなく、メインチェックアウトを守るための検査が働いた結果です。多くの場合、Claudeがメッセージ末尾の指示どおりにコマンドを書き直して先へ進みます。人が手を入れる必要があるのは、メインチェックアウトを意図して操作したいときくらいです。
読み取り専用の git -C がmainへ向かうケースや、PreToolUseフックやbypassでも通らない理由は、Claude Codeのworktreeはmainへの読み取り専用gitも拒否するで扱っています。ここでは、拒否の3つの理由ごとの書き直し方を扱います。
拒否メッセージはどう読むか
エラーリファレンスでは、この拒否を「Command blocked by the worktree isolation checks」の見出しで扱っています。対象はBash、PowerShell、Monitorの各コマンドで、worktreeに隔離されたセッションの中で実行されたものです。メッセージは必ず is isolated in the worktree <path>, but this command に続けて理由を書きます。
理由は次の3系統です。
拒否される3つの理由
実行場所がメインチェックアウトか別のworktree
メッセージに
resolved to the shared checkoutまたはis in a different worktreeと出ます。gitの向き先がメインチェックアウト
BashまたはMonitorのコマンドが、gitをメインチェックアウトへ向けています。
コマンドの文面から検証できない
gitを名指ししていなくても、実行時に値が決まる式があると拒否されます。
3つ目が一番つまずきやすい型です。変数の間接参照 ${!name} や、Bashの関数置換 ${ command; } は、実行時に出てくる値がそれ自体コマンドになり得ます。文面だけではその中身でgitが何をするか確かめられないため、gitに触れないコマンドでも止まります。
エラーリファレンスに載っているメッセージの例は次のとおりです。
This session is isolated in the worktree /path/to/worktree, but this command evaluates ${!x@P} arithmetically inside a construct too complex to verify, which can run a command hidden in a variable's value. Refusing to run it — a worktree-isolated session's git operations must target its own worktree. Split it into plain, separate commands and run them from /path/to/worktree.末尾の Split it into plain, separate commands and run them from /path/to/worktree. が、そのまま直し方の指示になっています。
理由別の直し方
メッセージはClaudeにツールエラーとして届き、worktreeの名前と進め方が添えられます。理由ごとの対処をまとめると次の形です。
| 理由 | メッセージの目印 | 対処 |
|---|---|---|
| メインチェックアウトで実行しようとした | メッセージの目印resolved to the shared checkout | 対処worktree内のディレクトリから実行し直す |
| 別のworktreeで実行しようとした | メッセージの目印is in a different worktree | 対処隔離先の自分のworktreeから実行し直す |
| gitをメインチェックアウトへ向けた | メッセージの目印git -C などの指定 | 対処worktree内で素のgitコマンドとして実行する |
| 文面を検証できない | メッセージの目印too complex to verify | 対処式を展開せず、プレーンなコマンドに分けて書く |
gitの向き先とコマンドの文面については、人が何かをする必要はありません。Claudeがメッセージを読んで書き直すのを待てば足ります。同じ式で何度も拒否され続けるときは、フラグの付いた値をその場で文字どおりに書き、gitは単独のプレーンなコマンドとしてworktreeの内側から実行します。
検証不能な式をプレーンに書き直す
間接参照を使ったコマンドを、値を直接書いた形へ開く例です。変数名は説明用で、実際の式は状況によって違います。
間接参照を値の直書きに開く
拒否されやすい書き方
変数の名前から値を引き、その結果を式の中で評価してgitに渡す書き方です。
通りやすい書き方
ブランチ名やパスをそのまま文字で書き、gitは1コマンドずつ分けて実行します。
コマンドで表すと、次のような差です(例示であり、特定のセッションで実際に出力された内容ではありません)。
# 拒否されやすい: 変数の間接参照を含む
name=BRANCH; git switch "${!name}"
# 通りやすい: 値を直接書き、worktreeの内側で単独実行
git switch feature/login-fixClaude側の運用として、CLAUDE.md に短い規約を置いておくと拒否の往復が減ります。以下は書き方の一例です。
## worktreeセッションでのgit操作
- gitは worktree 内で素のコマンドとして実行する(`git -C` や `GIT_DIR` を使わない)
- ブランチ名やパスは変数経由にせず、文字どおり書く
- 複数のgit操作は `&&` やサブシェルでつながず、1コマンドずつ実行する最後の1行は、公式の「plain, separate commands」に沿った書き方です。ただし、どこまで単純にすれば確実に通るかは検査の実装次第で、規約に書いたからといって拒否がゼロになる保証はありません。
検査が見ているもの
エラーの背景は、worktreeのドキュメントの「How Claude Code enforces isolation」節にあります。隔離中のセッションでは4つの検査が働きます。
- ファイル編集:
Edit、Write、NotebookEditが、メインチェックアウト内のパスを対象にしていないか - コマンドの作業ディレクトリ: Bash、PowerShell、Monitorの実行場所が、メインチェックアウトでないか。メインチェックアウトの外だと確かめられない場合も止まります
- gitのリダイレクト: BashとMonitorで、
git -C、--git-dir、GIT_DIRやGIT_WORK_TREEの変数、メインチェックアウトへのcdを経由したgitがないか - コマンドの形: コマンド名が実行時に決まる、構文を解析できない、
${!name}や${ command; }のような展開がある、といった場合
この4つ目は無効にできません。PowerShellに適用されるのは、作業ディレクトリの検査だけです。
隔離は、--worktree で起動したセッションでも、EnterWorktree で入ったセッションでも、再開したセッションでも同じルールです。セッションから起動するサブエージェントにも同じ検査が及びます。バックグラウンドセッションの隔離の仕組みは、worktree.bgIsolationでバックグラウンド編集を直接許可する仕組みでも扱っています。
検査の外にあるもの
4つの検査が読むのは、編集対象のパス、コマンドを実行するディレクトリ、コマンドの文面の3種類です。シェルコマンドがどのファイルへ書き込むかは追跡しません。そのため、gitをメインチェックアウトで走らせずに書き込む cp やシェルのリダイレクトは、この検査では拒否されません。そうしたコマンドは通常のシェルコマンドと同じく、権限設定とサンドボックスの設定で扱われます。「隔離されているからメインには何も起きない」とは読めない点です。
メインチェックアウトを意図して操作したいとき
メインチェックアウトを操作する用事そのものがある場合、隔離中のセッションからは通りません。エラーリファレンスの対処は、セッションの外の端末で自分で実行することです。
メインチェックアウトの操作を人が引き受ける流れ
- 1
拒否の理由を確認する
resolved to the shared checkoutや、gitの向き先がメインを指している旨が出ていれば、意図した拒否です。 - 2
セッション外の端末を開く
隔離されたClaude Codeセッションとは別のターミナルを使います。
- 3
メインチェックアウトで自分で実行する
必要なgit操作や作業を、人の手で実行します。
Claudeに回避させる方向ではなく、この線引きを受け入れたほうが、worktreeを使う意味と整合します。
名前の似た別のエラーとの切り分け
worktreeの隔離まわりには、見た目の似たメッセージが他にもあります。どれに当たったかで原因が変わります。
| メッセージの冒頭 | 何が起きたか | 向き合い方 |
|---|---|---|
is isolated in the worktree <path>, but this command | 何が起きたかコマンドの実行場所・gitの向き先・文面が検査に引っかかった | 向き合い方本記事。書き直す |
This write was blocked because the path is spelled in a form that cannot be safely resolved | 何が起きたか書き込み先のパスの綴りがシンボリックリンク等で解決できない | 向き合い方直接のシンボリックリンクなしのパスで指定し直す |
Refusing to use <path> as an isolation worktree | 何が起きたかディレクトリのgit情報がメインチェックアウトに解決された | 向き合い方続くメッセージの終わり方に従う |
2つ目はファイル書き込みやコマンドの作業ディレクトリのパス綴りの問題で、コマンドの文面とは別の検査です。3つ目はworktreeを隔離先として採用する段階の拒否で、再開時の問題はClaude Codeのworktreeが再利用されるバグとも近い領域です。バックグラウンドセッションで別の理由のコマンド拒否に当たった場合は、「Commands refused」エラーの原因と対処を見てください。
検査はどう厳しくなってきたか
隔離検査は、バージョンを追って細かく調整されています。changelogから、この拒否に関わるものを拾うと次のとおりです。
隔離検査に関わる変更
- v2.1.222全セッション種別に適用
隔離されたセッションとサブエージェントが、メインチェックアウトに対して破壊的なgitコマンドを実行できてしまう問題を修正。ファイル編集とBashの隔離が、すべてのセッション種別に適用されるようになりました。
- v2.1.257過剰な拒否を緩和
gitに触れないBashのループ、
$VARの読み取り、"$(…)"、ヒアドキュメントが「検証できない」として拒否される問題を修正しました。 - v2.1.274入れ子の展開を拒否
ネストしたシェル展開を含むBashコマンドを、隔離セッションが受け入れてしまう問題を修正し、拒否するようになりました。
- v2.1.299awkプログラム
隔離すべきでないものを通してしまうawkプログラムの扱いを修正しました。
- v2.1.309ロケール接頭辞とzshの算術
ロケール接頭辞付きのコマンドと、zshの一部の算術コマンドを、隔離ガードが拒否するよう修正しました。
v2.1.257は拒否を減らす方向、それ以外は取りこぼしを塞ぐ方向の修正です。同じコマンドが、バージョンによって通ったり拒否されたりするのはこのためです。以前は通った式が急に止まるときは、claude --version でバージョンを確かめ、上の時系列と照らすと原因の見当がつきます。
まとめ
拒否メッセージは、読めばほぼ直し方が書いてあります。実行場所をworktreeの内側にそろえ、gitの向き先を指定せず、変数の間接参照のような実行時に決まる式を値の直書きに開くこと。この3点で大半は片付きます。メインチェックアウトを操作する必要があるなら、セッションの外から人が実行するのが筋です。隔離の全体像はClaude Code Worktree実践ガイドにまとまっています。