claude-code - 💡(How to fix) Fix PreToolUse hook on Agent tool fires but does not block execution [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#46044Fetched 2026-04-11 06:30:26
View on GitHub
Comments
1
Participants
2
Timeline
8
Reactions
0
Author
Timeline (top)
labeled ×6commented ×1cross-referenced ×1

PreToolUse hook with matcher: "Agent" fires correctly (stdin payload received, script executes, exit code 1 returned) but does not actually block the Agent tool from executing. The Explore subagent proceeds regardless of the deny signal.

Root Cause

PreToolUse hook with matcher: "Agent" fires correctly (stdin payload received, script executes, exit code 1 returned) but does not actually block the Agent tool from executing. The Explore subagent proceeds regardless of the deny signal.

Fix Action

Fix / Workaround

Workarounds attempted

Code Example

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Agent",
        "hooks": [
          {
            "type": "command",
            "command": "python3 .claude/block-explore.py"
          }
        ]
      }
    ]
  }
}

---

import json, sys

payload = json.loads(sys.stdin.read())
desc = payload.get('tool_input', {}).get('description', '').lower()

if 'explore' in desc:
    print('BLOCKED: Use pre-built context files instead of Explore agent.')
    sys.exit(1)  # Should deny the tool

---

{
  "session_id": "...",
  "tool_name": "Agent",
  "tool_input": {
    "description": "Explore some service methods",
    "prompt": "Search for patterns in the codebase...",
    "subagent_type": "Explore"
  },
  "hook_event_name": "PreToolUse"
}
RAW_BUFFERClick to expand / collapse

Summary

PreToolUse hook with matcher: "Agent" fires correctly (stdin payload received, script executes, exit code 1 returned) but does not actually block the Agent tool from executing. The Explore subagent proceeds regardless of the deny signal.

Environment

  • Claude Code CLI (macOS, Darwin 25.4.0)
  • Model: claude-sonnet-4-6
  • Permission mode: plan

Setup

.claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Agent",
        "hooks": [
          {
            "type": "command",
            "command": "python3 .claude/block-explore.py"
          }
        ]
      }
    ]
  }
}

block-explore.py:

import json, sys

payload = json.loads(sys.stdin.read())
desc = payload.get('tool_input', {}).get('description', '').lower()

if 'explore' in desc:
    print('BLOCKED: Use pre-built context files instead of Explore agent.')
    sys.exit(1)  # Should deny the tool

What happens

  1. Hook script runs ✅ (confirmed via debug log — full payload received)
  2. Script detects keyword in description ✅
  3. Script prints deny message and exits with code 1 ✅
  4. Agent/Explore tool executes anyway

Debug log (actual payload received by hook)

{
  "session_id": "...",
  "tool_name": "Agent",
  "tool_input": {
    "description": "Explore some service methods",
    "prompt": "Search for patterns in the codebase...",
    "subagent_type": "Explore"
  },
  "hook_event_name": "PreToolUse"
}

Expected behavior

Exit code 1 from a PreToolUse hook should deny/block the Agent tool call, same as it does for Bash, Edit, and other tools.

Use case

We maintain pre-built context maps (wiki + knowledge graph notes) for each project. We want to enforce a lookup-first strategy via hooks — read pre-built context before allowing broad file exploration. Without the ability to block the Agent tool via hooks, Claude defaults to Explore agents (~50K tokens) instead of targeted reads from pre-built context (~4K tokens).

Workarounds attempted

  • CLAUDE.md instructions — ignored for complex planning tasks
  • hookify plugin action: block on prompt event — does not intercept Agent tool
  • PreToolUse hook with exit code 1 — fires but doesn't block (this issue)

🤖 Generated with Claude Code

extent analysis

TL;DR

The PreToolUse hook with a non-zero exit code may not be correctly blocking the Agent tool due to potential inconsistencies in hook handling for specific tool types.

Guidance

  • Review the Claude Code CLI documentation to ensure that the PreToolUse hook is supported and correctly configured for the Agent tool.
  • Verify that the hook script is correctly implemented and that the exit code is being properly propagated to the CLI.
  • Consider adding additional logging or debugging statements to the hook script to confirm that it is being executed as expected.
  • Check if there are any known issues or limitations with the PreToolUse hook in the Claude Code CLI version being used.

Example

No code snippet is provided as the issue seems to be related to the configuration or handling of the PreToolUse hook rather than the code itself.

Notes

The issue may be specific to the Agent tool or the Claude Code CLI version being used. Further investigation and debugging may be required to determine the root cause of the issue.

Recommendation

Apply workaround: Modify the hook script to handle the Agent tool execution directly, if possible, or explore alternative methods to block the Agent tool, such as using a different hook or plugin.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Exit code 1 from a PreToolUse hook should deny/block the Agent tool call, same as it does for Bash, Edit, and other tools.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING