Plugin PostToolUse command hook (exit 2) output not injected into model context

Resolved 💬 3 comments Opened Apr 10, 2026 by richardpeng Closed Apr 14, 2026

Description

A command-type PostToolUse hook defined in a plugin's hooks.json detects a keyword in Bash output and exits with code 2 + a message. The message is not injected into the model's context, so the model proceeds without acting on it.

Environment

  • Claude Code 2.1.x (latest)
  • macOS Darwin 25.4.0
  • Opus 4.6 (1M context)
  • Hook defined in a plugin installed via the plugin marketplace

Plugin hooks.json

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PLUGIN_ROOT}/hooks/detect-sonar-in-output.sh"
          }
        ]
      }
    ]
  }
}

Hook script (detect-sonar-in-output.sh)

#!/usr/bin/env bash
input=$(cat)
stdout=$(echo "$input" | jq -r '.tool_result.stdout // empty')
stderr=$(echo "$input" | jq -r '.tool_result.stderr // empty')
combined="$stdout $stderr"

if echo "$combined" | grep -qi "sonarqube"; then
  echo "SonarQube detected in command output. You MUST invoke the /sonarqube skill."
  exit 2
fi

Steps to reproduce

  1. Install a plugin with the above PostToolUse hook
  2. Ask about a PR that has a SonarQube check run: "What details can you find on this PR? https://github.com/org/repo/pull/229"
  3. The model runs gh pr checks 229 via Bash, which returns output containing "SonarQube Code Analysis"
  4. The PostToolUse hook should fire, detect "sonarqube" in the output, and exit 2 with a message

Expected behavior

The hook's stdout message is injected into the conversation as additional context, and the model acts on it (invokes the sonarqube skill).

Actual behavior

The model proceeds to summarize the PR check results without invoking the skill. No hook output or error is shown in the transcript for the PostToolUse event. The hook appears to either not fire or its output is silently discarded.

Notes

  • A separate agent-type PreToolUse hook error ("Messages are required for agent hooks") does appear in the same session on the first Bash call. That error is from a different hook (not this plugin) and is tracked in #39184. It's unclear whether the agent hook error on PreToolUse prevents command-type PostToolUse hooks from running on subsequent Bash calls.
  • The plugin's PreToolUse hook on WebFetch|Fetch (also command-type) is not triggered in this flow since the model uses Bash, not WebFetch.
  • Command-type PostToolUse hooks are documented as working in #39184's compatibility table, so this may be specific to plugin-defined hooks vs settings-defined hooks.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗