WindowsでClaude Codeのフックを設定していると、フックのコマンドが動かないのにツール呼び出しだけ進んでしまうことがあります。特にGit Bashが入っていない環境で、コマンドを引用符だけで囲んでいる場合です。
Claude Code v2.1.310で、この問題が修正されました。PreToolUseとPermissionRequestのフックが、Git BashのないWindows環境でツール呼び出しを通してしまうことがあったのです。
今回はこの修正を、無人実行でフックを使うときの確認ポイントとして整理します。修正されたからすべてのフックが動く、という話ではありません。そこは分けて考えましょう。
フックが動かないと何が困るのか
フックは、ツールを呼ぶ前後に確認処理を入れる仕組みです。たとえば、危険な操作の前に検査したり、処理の終わりにログを残したりできます。
PreToolUseはツール実行前、PermissionRequestは許可を求める場面で動きます。ここでフックが失敗したのに、Claude Code側が「確認できた」と扱ってしまうと困ります。
簡単な例を作ってみましょう。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "\"C:\\tools\\check-command.ps1\""
}
]
}
]
}
}
ここではPowerShellスクリプトのパス全体を引用符で囲んでいます。パスに空白がある場合には必要になる書き方ですが、実行環境に依存する部分があります。
v2.1.310でWindowsの判定が直った
v2.1.310の公式リリースノートには、WindowsでGit Bashが見つからず、フックのコマンドが引用符だけで書かれている場合の修正が記載されています。
修正前は、PreToolUseとPermissionRequestのフックがツール呼び出しを通してしまう場合がありました。フックを実行できないなら、許可の判断材料が無いので止まるべきです。
ここは小さな修正に見えますが、無人実行では大きいです。人が画面を見ていれば異常に気付きますが、スケジュール実行では「通ってしまった」こと自体が見えません。
まずバージョンを確認しましょう
では、最初にClaude Codeのバージョンを確認してみましょう。
claude --version
v2.1.310以降なら、今回の修正を含む版です。古い版の場合は、同じ設定でも挙動が違う可能性があります。
バージョンを確認したら、次にGit Bashの有無を確認します。
where.exe bash
where.exe git
パスが表示されたら、その実体がGit Bashなのか、WSLや別のbashなのかを確認してください。bash.exeが見つかっただけで、Git Bashが使えるとは限りません。
引用符だけのコマンドは見直す
今回の修正対象は、Git Bashが無いことと、フックのコマンドが引用符だけで書かれていることの組み合わせです。
WindowsのPowerShellスクリプトを呼ぶなら、実行するシェルを明示したほうが読みやすくなります。
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\tools\check-command.ps1"
ただし、実行ポリシーを変える指定は環境のルールに合わせてください。会社や共有環境で勝手に緩めるものではありません。
Git Bashが必要なフックなら、Git for Windowsのインストールを前提にするのか、PowerShellだけで完結させるのかを決めます。両方を混ぜると、別のWindowsマシンで再現しなくなります。
フックの失敗を成功と混同しない
フックを追加したら、わざと簡単な失敗を作って確認しましょう。たとえば、検査スクリプトが特定の文字列を見つけたら終了コード1を返すようにします。
if ($env:CLAUDE_CODE_TEST_HOOK -eq "deny") {
Write-Error "hook denied"
exit 1
}
exit 0
この状態でツール呼び出しが止まるかを確認します。「フックのログが出た」だけでは不十分です。終了コードがClaude Code側の判断に反映されているかまで見てください。
逆に、Git Bashが無い環境でフックが呼べないなら、ツール呼び出しがそのまま通らないことを確認します。今回の修正は、まさにこの境界を正しく扱うためのものです。
無人実行ではログを残しましょう
無人実行のフックは、成功した時より失敗した時に役立ちます。フックの標準出力と終了コードをログに残してください。
$log = "C:\logs\claude-hook.log"
"$(Get-Date -Format o) hook=$env:CLAUDE_CODE_TEST_HOOK" | Add-Content $log
exit 0
ログの保存先が存在しない場合に、ログ処理そのものが失敗しないように注意してください。監視用の処理が本体を止めると、原因が分かりにくくなります。
機密情報やトークンをログに書かないことも重要です。コマンドライン全体をそのまま保存するより、必要な項目だけを選んで記録したほうが安全です。
というわけで
Claude Code v2.1.310では、WindowsでGit Bashが無い場合に、引用符だけのフックコマンドがツール呼び出しを通してしまう問題が修正されました。
フックは設定を書いたら終わりではありません。バージョン、実行シェル、終了コード、失敗時のログを順番に確認してください。
無人実行では、動かないフックが何も言わずに通るのが一番怖いです。今回の修正をきっかけに、止まるべき処理が本当に止まるかを一度テストしてみてください。


コメント