原文(日本語)
フックがブロッキングエラー(終了コード2)を返した際に、stderrがユーザーに表示されない問題を修正しました。
原文(英語)
Fixed hook blocking errors (exit code 2) not showing stderr to the user
概要
Claude Code v2.1.41では、カスタムフック(hooks)が終了コード2(ブロッキングエラー)で終了した際に、標準エラー出力(stderr)の内容がユーザーに表示されない問題が修正されました。これにより、フックが処理をブロックした理由を正確に理解できるようになりました。
問題の背景
Hooksとは
Claude Codeでは、特定のイベント(ツール呼び出し、メッセージ送信など)に対して、カスタムスクリプト(hooks)を実行できます。フックは、操作を許可(exit 0)、拒否(exit 2)、または警告(exit 1)を返すことができます。
終了コード2の意味
- exit 0: 操作を許可
- exit 1: 警告を表示するが、操作は継続
- exit 2: 操作をブロック(拒否)
発生していた問題
フックがexit 2で終了した際、ブロックされたことは通知されるものの、なぜブロックされたのか(stderrの内容)が表示されませんでした。
基本的な使い方
フックの設定例
.claude/hooks/tool-call.shを作成して、特定の条件でツール呼び出しをブロックします。
bash
#!/bin/bash
# .claude/hooks/tool-call.sh
TOOL_NAME="$1"
# 本番環境でのBashツール使用をブロック
if [ "$TOOL_NAME" = "Bash" ] && [ "$ENVIRONMENT" = "production" ]; then
echo "Error: Bash tool is not allowed in production environment" >&2
echo "Use safe alternatives or request approval from the team lead" >&2
exit 2
fi
exit 0修正前の動作
bash
> bash -c "rm -rf /tmp/test"
# 修正前: ブロックされたことは分かるが、理由が不明
❌ Operation blocked by hook修正後の動作
bash
> bash -c "rm -rf /tmp/test"
# 修正後: stderrの内容が表示される
❌ Operation blocked by hook
Error: Bash tool is not allowed in production environment
Use safe alternatives or request approval from the team lead実践例
セキュリティチェックフック
本番環境での危険なコマンド実行を防ぐフックです。
bash
#!/bin/bash
# .claude/hooks/tool-call.sh
if [ "$TOOL_NAME" = "Bash" ]; then
COMMAND="$2"
# 危険なパターンをチェック
if echo "$COMMAND" | grep -qE "rm -rf|dd if=|mkfs|format"; then
echo "⚠️ SECURITY WARNING: Destructive command detected" >&2
echo "Command: $COMMAND" >&2
echo "This operation is blocked for safety. Please review and use /bypass if needed." >&2
exit 2
fi
fi
exit 0実行時の表示:
bash
> bash -c "rm -rf /data"
❌ Operation blocked by hook
⚠️ SECURITY WARNING: Destructive command detected
Command: rm -rf /data
This operation is blocked for safety. Please review and use /bypass if needed.コードレビュー必須チェック
コミット前のレビュー必須を強制するフックです。
bash
#!/bin/bash
# .claude/hooks/tool-call.sh
if [ "$TOOL_NAME" = "Bash" ] && echo "$2" | grep -q "git commit"; then
# レビューステータスを確認
if ! git log -1 --pretty=%B | grep -q "Reviewed-by:"; then
echo "❌ Commit blocked: Code review required" >&2
echo "Please add 'Reviewed-by: <name>' to your commit message" >&2
echo "Or request review first using /review-pr" >&2
exit 2
fi
fi
exit 0実行時の表示:
bash
> git commit -m "Add new feature"
❌ Operation blocked by hook
❌ Commit blocked: Code review required
Please add 'Reviewed-by: <name>' to your commit message
Or request review first using /review-prファイル変更の制限
特定のファイルへの変更を制限するフックです。
bash
#!/bin/bash
# .claude/hooks/tool-call.sh
if [ "$TOOL_NAME" = "Edit" ] || [ "$TOOL_NAME" = "Write" ]; then
FILE_PATH="$2"
# 保護されたファイルのチェック
if echo "$FILE_PATH" | grep -qE "production.config|secrets.json|.env.prod"; then
echo "🔒 File modification blocked: Protected configuration file" >&2
echo "File: $FILE_PATH" >&2
echo "Reason: This file requires manual review and approval" >&2
echo "Please create a PR instead or contact the DevOps team" >&2
exit 2
fi
fi
exit 0実行時の表示:
bash
> (production.configファイルを編集しようとした場合)
❌ Operation blocked by hook
🔒 File modification blocked: Protected configuration file
File: production.config
Reason: This file requires manual review and approval
Please create a PR instead or contact the DevOps team営業時間外の制限
営業時間外の本番環境への変更を防ぐフックです。
bash
#!/bin/bash
# .claude/hooks/tool-call.sh
HOUR=$(date +%H)
DAY=$(date +%u) # 1=月曜, 7=日曜
# 平日の営業時間外(18時〜9時)または週末
if ([ "$HOUR" -lt 9 ] || [ "$HOUR" -ge 18 ]) || [ "$DAY" -ge 6 ]; then
if [ "$ENVIRONMENT" = "production" ] && [ "$TOOL_NAME" = "Bash" ]; then
echo "⏰ Operation blocked: Outside business hours" >&2
echo "Production changes are restricted to weekdays 9:00-18:00" >&2
echo "For emergency changes, contact on-call engineer" >&2
exit 2
fi
fi
exit 0この修正の利点
デバッグの容易化
- ブロックされた理由が明確に表示される
- フックのロジックを理解しやすい
- 問題解決のための情報が得られる
ユーザー体験の向上
- エラーメッセージが分かりやすい
- 次のアクションが明確に示される
- フックの存在と動作を理解しやすい
セキュリティと安全性
- ポリシー違反の理由が明示される
- 適切な代替手段が提案される
- セキュリティルールの透明性が向上
注意点
- フックスクリプトは実行可能権限が必要です(
chmod +x .claude/hooks/*.sh) - stderrに機密情報を含めないよう注意してください
- 修正後は、ブロッキングエラーの理由が必ず表示されるため、適切なエラーメッセージを設定することが重要です
Hooksのベストプラクティス
- エラーメッセージは明確で具体的に
- 代替案や次のアクションを提示
- セキュリティルールは文書化する
- 緊急時のバイパス方法を用意