Activity, over time
Daily observations from the public event archive.
Attention
Daily stars & forks
Star accumulation
Cumulative stars
Pull requests
Daily opens & merges
Conversations
Daily issues & comments
Community
Daily accounts & reviews
Releases
Daily releases
Trending history
Daily top 10 · last 90 days · UTC
Mentions
Stars
Forks
Contributors
Latest stargazers
The last 10 distinct accounts we observed this year.
Most active participants
PR, issue, comment & review events in the past year.
Packages
No packages found.
README badges
Embed a badge in your README or website.
Live mentions · last 30 days
Mentions
Claude Code 2.1.303 の PowerShell hook が node の exit 2 で止まらない:7通りの実測表 Windows で "shell": "powershell" を指定した hook は、呼んだ node などが exit 2 で終わっても、Claude Code 2.1.303 では操作を止めませんでした。Windows PowerShell 5.1 の -Command が終了コード 2 を 1 に変えるためです。2.1.309 ではこの書き方は止まりましたが、node の後ろに Write-Output を続けた書き方は、2.1.309 でも素通りしました。command の最後に ; exit $LASTEXITCODE を足せば、どちらの版でも止まりました。 危ない操作を止めるつもりで PowerShell の hook を書いた人は、止まっていないことに気づきにくいと思います。私の環境では、2.1.303 で止まらなかったとき、Claude の返答に hook の表示は何も出ませんでした。この記事では、同じ hook の書き方7通りを試した表(うち5通りは 2.1.303 と 2.1.309 の両方で、残り2通りは 2.1.303 だけ)と、それぞれの直し方を載せます(Windows 11・Windows PowerShell 5.1・2026-10-23 の実測です)。 7通りの書き方の実測表(5通りは 2.1.303 と 2.1.309 の両方) PreToolUse(matcher は Write)に、exit 2 で終わる hook を置きました。Claude に Write でファイルを1つ作らせ、ファイルができたら「通った」、できなかったら「止まった」としています。 書き方 command の中身 2.1.303 2.1.309 止まったときの表示 A "shell": "powershell"・node C:/.../exit2.js 通った(2回とも) 止まった 2.1.309: PreToolUse:Write hook error: [node C:/.../exit2.js]: blocked by exit2.js B A の後ろに ; exit $LASTEXITCODE 止まった 止まった blocked by exit2.js C PowerShell の中で [Console]::Error.WriteLine('blocked by ps exit 2'); exit 2 止まった 止まった blocked by ps exit 2 D shell の指定なし(Git Bash)・node exit2.js 止まった 止まった blocked by exit2.js E A の後ろに ; Write-Output checked 通った 通った なし F A に "onFailure": "block" 止まった 未測 failed; blocking because onFailure is "block" の次の行に blocked by exit2.js G exec form("command": "node"・"args": ["C:/.../exit2.js"]) 止まった 未測 blocked by exit2.js 試した回数は各1回で、A の 2.1.303 だけ2回です。2.1.303 はこの PC に入れている本体、2.1.309 は一時フォルダに npm で入れた別の実行ファイルで試しました。 自分の hook がどれに当たるかで、やることは次のとおりです。 A(PowerShell で外のプログラムを呼ぶだけ): 2.1.309 では止まった。2.1.303 では止まらなかったので、B か G に書き換える E(呼んだ後ろに別のコマンドがある): 後ろに Write-Output を続けた書き方は 2.1.309 でも止まらなかった。B のように最後を exit $LASTEXITCODE にする C・D(PowerShell 自身が exit 2 する、Git Bash で動かす): そのままで止まる 起きたこと hook のスクリプトは、標準エラーに理由を書いて終了コード 2 で終わるだけの2行です。 process.stderr.write("blocked by exit2.js\n"); process.exit(2); これを PreToolUse の hook にして、"shell": "powershell" で動かしました。設定は次の形です(パスは伏せています)。 { "hooks": { "PreToolUse": [ { "matcher": "Write", "hooks": [ { "type": "command", "shell": "powershell", "command": "node C:/.../exit2.js" } ] } ] } } 2.1.303 では、Write はそのまま実行されてファイルができました。2回試して2回ともです。Claude の返答は「ブロックはされませんでした」で、hook の表示は出ていません。 同じ command から "shell": "powershell" を外し、Git Bash で動くようにすると止まりました。Windows でも Git Bash が入っていれば、shell を指定しない hook は Git Bash で動きます(公式ドキュメントでは、Git Bash が入っていない Windows では既定が PowerShell です)。この件は前の記事に書いています。 試した環境 Windows 11 Claude Code 2.1.303(本体) Claude Code 2.1.309(一時フォルダに npm install @anthropic-ai/claude-code@2.1.309 で入れた別の実行ファイル) Windows PowerShell 5.1.26100.9711(PowerShell 7 の pwsh は入っていません) Node v24.14.1 Git Bash 5.2.37 確認日: 2026-10-23 原因: PowerShell 5.1 の -Command は終了コード 2 を 1 にする Claude Code の hook では、終了コード 2 だけが「ブロック」です。公式ドキュメントは、exit 2 を Blocking error(PreToolUse ならツールの呼び出しを止める)、それ以外の終了コードを Non-blocking error(操作は進む)と分けています。 一方、Windows PowerShell 5.1 の -Command は、最後に動いた外部プログラムの終了コードをそのまま返しません。Microsoft のドキュメント(about_PowerShell_exe)には、最後のコマンドが外部プログラムで、終了コードが 0 でも 1 でもないときは、プロセスの終了コードを 1 に変えると書かれています。同じ箇所に、終了コードを残したいときは exit $LASTEXITCODE を足すように、とあります。 そのため、node は 2 で終わっているのに、2.1.303 の Claude Code には 2 ではなく 1 が届いていると考えられます(下の PowerShell 単体の結果と、後で書く F の表示からの推測で、Claude Code が受け取った値そのものは測っていません)。1 は止めないエラーなので、Write はそのまま進みます。 PowerShell 単体で終了コードを確かめた Claude Code を通さずに、PowerShell だけで同じことを確かめました。exit2.js は上の2行のスクリプトです。どれも Git Bash から打ち、直後の echo "rc=$?" で終了コードを見ました($LASTEXITCODE は Git Bash に先に展開されないよう \$ でエスケープしています)。 実行したコマンド 終了コード bash -c "node exit2.js" 2 powershell -NoProfile -Command "node exit2.js" 1 powershell -NoProfile -Command "node exit2.js; exit $LASTEXITCODE" 2 powershell -NoProfile -Command "node exit2.js; Write-Output after" 0(after が出る) powershell -NoProfile -Command "exit 2" 2 powershell -NoProfile -Command "[Environment]::Exit(2)" 2 外のプログラムの 2 は 1 になり、PowerShell 自身の exit 2 は 2 のまま返ります。表の C が 2.1.303 でも止まったのは、このためだと考えられます。 -File で、node を呼ぶ1行だけの .ps1 を実行したときは、node が失敗(終了コード 1)しても 0 が返りました。最後に exit $LASTEXITCODE を書くと、node の終了コードが返りました。hook から .ps1 を呼んでいる人は、こちらも確かめてください。 2.1.309 で直ったこと、直っていないこと 2.1.309 の CHANGELOG に、次の1行があります(2026-10-23 に CHANGELOG.md の原文で確認)。 Fixed hooks that run in PowerShell not blocking when the hook's program exits with code 2, and on Windows PreToolUse and PermissionRequest hooks with "shell": "powershell" failing open when Git for Windows isn't installed 実際に、同じ設定の A は 2.1.303 では通り、2.1.309 では止まりました。表示は PreToolUse:Write hook error: [node C:/.../exit2.js]: blocked by exit2.js です。 ただし E(node C:/.../exit2.js; Write-Output checked)は、2.1.309 でも通りました(1回の結果です)。PowerShell 単体の表のとおり、後ろに別のコマンドがあると、終了コードはその後ろのコマンドの成否で決まります。Write-Output は成功するので 0 になり、node の 2 は残りません。終了コードは最後のコマンドで決まるという PowerShell の仕様なので、版を上げてもこの点は変わらない可能性が高いと考えています。 ! 版を上げるだけでは足りない場合があります。 後ろに Write-Output を続けた書き方は、2.1.309 でも止まりませんでした。プログラムを呼んだ後ろにほかのコマンドを足している場合は、最後を exit $LASTEXITCODE にしてください。 onFailure: block の表示から分かること F は、A に "onFailure": "block" を足したものです(2.1.303)。止まりはしましたが、表示は次の2行でした。 failed; blocking because onFailure is "block" blocked by exit2.js 「exit 2 だから止めた」ではなく、「hook が失敗した。onFailure が block なので止める」という表示です。2.1.303 では、この hook が exit 2 のブロックとしてではなく、ただの失敗として扱われたことが、この表示から分かります。 onFailure: block は、1 も失敗として止めるので、今回の症状には効きます。ただ、理由の表示が「failed」になるので、本当に hook が壊れて失敗したときと見分けにくくなります。onFailure の動きは別の記事で試しています。 直し方 次のどれかを使います。上から順に、手を入れる量が少ないものです。 command の最後に ; exit $LASTEXITCODE を付ける(表の B)。2.1.303・2.1.309 の両方で止まりました { "type": "command", "shell": "powershell", "command": "node C:/.../exit2.js; exit $LASTEXITCODE" } exec form に書き換える(表の G)。command に実行ファイル、args に引数を分けて書くと、shell を通らずにプログラムが直接動きます。公式ドキュメントでは、shell は「Ignored when args is set」(args があると無視)です。私は "shell": "powershell" を残したまま試し、2.1.303 で止まりました { "type": "command", "command": "node", "args": ["C:/.../exit2.js"] } "onFailure": "block" を足す(表の F)。止まりますが、表示が「failed」になります。onFailure は公式ドキュメントで v2.1.295 以降が必要とされています Claude Code を 2.1.309 以降に上げる。私の環境では A の書き方は 2.1.309 で止まりましたが、E(後ろに Write-Output を続けた書き方)は 2.1.309 でも止まらなかったので、1〜3 のどれかと併せます PowerShell の処理をまとめて書きたいときは、表の C のように PowerShell 自身で exit 2 を返す書き方でも、両方の版で止まりました。 確認のしかた 直したら、実際に止まるかを一度試してください。私は、一時フォルダで次の形の claude -p を動かし、out.txt ができたかどうかで判定しました(プロンプトは途中を省いています)。 claude -p --settings <設定のファイル> --permission-mode acceptEdits --max-turns 3 "Use the Write tool exactly once to create out.txt ..." out.txt ができなければ止まっています。止まったときは、hook が標準エラーに書いた理由(今回なら blocked by exit2.js)が表示に出ました。 終了コードだけ先に見たいときは、PowerShell 単体の表のように、hook と同じ command を powershell -NoProfile -Command で動かします。PowerShell のプロンプトから打つときは、外側をシングルクォートにしてください。ダブルクォートのままだと、$LASTEXITCODE が外側の PowerShell で先に展開され、表と同じ結果になりません。 powershell -NoProfile -Command 'node exit2.js; exit $LASTEXITCODE' $LASTEXITCODE 2 行目の $LASTEXITCODE で、中の PowerShell の終了コードが出ます(cmd から打つ場合は echo %ERRORLEVEL% で見ます)。私の環境では、単体で 2 が返る書き方(表の B・C)は、2.1.303 でも 2.1.309 でも止まりました。一方、2.1.309 では単体で 1 になる A も止まりました。単体の結果は、2 が返るかどうかを見る目安にとどめ、最後は上の claude -p の形で止まるかを確かめてください。 似た症状・注意点 "shell": "powershell" は、公式ドキュメントでは「Windows で PowerShell を使って command を動かす」設定です。この PC には pwsh(PowerShell 7)がなく、Windows PowerShell 5.1 で動きました。一方で、2.1.247 の Windows 11 で shell: powershell が pwsh を起動し、pwsh がない PC では hook が動かないという報告(anthropics/claude-code の issue #90077)もあります。版や環境で違う可能性があるので、自分の PC で試してください PowerShell が exit 2 を 1 に変える件は、ほかのツールでも踏まれています。kenn-io/kit の PR #158(2026-10-06)は、PowerShell の形では hook の exit 2 が 1 になるため、Windows の Claude Code の hook を exec form に変えた変更です 2.1.309 の同じ行には、Git for Windows が入っていない Windows で "shell": "powershell" の PreToolUse・PermissionRequest の hook が止まらずに通っていた(failing open)件の修正も書かれています。この件は私の環境(Git Bash あり)では試していません 自分の hook が止まっているかどうかは、設定を読むだけでは分かりにくいです。一度、わざと exit 2 で終わる hook で試してみてください。 関連記事(Windows で Claude Code の hook) Claude Code の hook が Windows で PowerShell にならない原因は Git Bash Claude Code hook の onFailure: block でも止まらない出力と、止まる exit 1 Windows の改行コードの件は Claude Code の Write で CRLF が LF に変わり git diff が全行になる原因と直し方 に書いています。 参考 Hooks reference(Claude Code Docs) CHANGELOG.md(anthropics/claude-code) about_PowerShell_exe(Microsoft Learn・PowerShell 5.1) kenn-io/kit PR #158 anthropics/claude-code issue #90077