原文(日本語に翻訳)
SessionStart、Setup、SubagentStart フックが終了コード2で終了した際に、stderrが無言で隠されてしまっていた問題を修正 — 今後はそのエラーがトランスクリプトに表示される
原文(英語)
Fixed SessionStart, Setup, and SubagentStart hooks silently hiding stderr when exiting with code 2 — the error is now shown in the transcript
概要
SessionStart・Setup・SubagentStart の各フックイベントは、PreToolUse などとは異なり処理をブロックできないイベントです。そのため終了コード2で終了した場合でも、セッションの開始やサブエージェントの起動処理自体は続行されます。しかし、これまではこのケースでフックが出力したstderrがどこにも表示されず、デバッグログにしか残らないため、フックが失敗していることに気づきにくいという問題がありました。修正後は、これら3つのイベントが終了コード2で終了した際、stderrの内容が <hook name> hook error という通知としてトランスクリプトに表示されるようになりました。
基本的な使い方
修正前:
1. SessionStart(または Setup / SubagentStart)フックを設定し、
何らかのチェックに失敗した場合に exit 2 で終了するようにする
2. セッションを開始する
3. ❌ フックは失敗しているのに、stderrの内容はトランスクリプトに表示されず
デバッグログを見ない限り気づけない
修正後:
1. 同じフック設定でセッションを開始する
2. フックが exit 2 で終了すると
3. ✅ `<hook name> hook error` という通知としてstderrの内容が
トランスクリプトにそのまま表示される実践例
SessionStartフックで環境チェックが失敗したことに気づけるようにする
#!/bin/bash
# .claude/hooks/session-start-check.sh
if ! command -v docker &> /dev/null; then
echo "docker コマンドが見つかりません。事前にインストールしてください" >&2
exit 2
fi修正前はこのメッセージがトランスクリプトに出ず見落とされがちでしたが、修正後はセッション開始時にトランスクリプト上へ SessionStart hook error として表示されます。
Setupフックでの初期化失敗を可視化する
#!/bin/bash
# .claude/hooks/setup.sh
if ! npm install --silent; then
echo "依存関係のインストールに失敗しました" >&2
exit 2
fiSetup フックはブロッキングできないため処理自体は続行されますが、修正後は失敗の事実と理由がトランスクリプト上に残るため、後から原因を追いやすくなります。
SubagentStartフックでサブエージェントごとの前提条件チェックを行う
#!/bin/bash
# .claude/hooks/subagent-start.sh
if [ ! -f "./.env.test" ]; then
echo "テスト用の .env.test が見つかりません。デフォルト設定で続行します" >&2
exit 2
fiサブエージェントの起動自体は継続しますが、修正後は「デフォルト設定で続行した」という事実がトランスクリプト上の通知として残るため、後からの調査がしやすくなります。
注意点
SessionStart・Setup・SubagentStartは元々ブロッキング不可のイベントであり、終了コード2で終了してもセッション開始・セットアップ完了・サブエージェント起動そのものを止めることはできません- 終了コード2の場合、stdoutの内容は無視されます。Claude自身にコンテキストとしてフィードバックを渡したい場合は
additionalContextを使用してください - 本修正はv2.1.199時点の挙動です。それ以前のバージョンではstderrはデバッグログにのみ書き込まれ、トランスクリプトには表示されません