Hookify plugin: 'stop' event rules incorrectly fire on all tool uses

Resolved 💬 3 comments Opened Dec 14, 2025 by yevhen Closed Dec 18, 2025

Problem

The hookify plugin's event: stop rules are incorrectly firing on every tool use (Read, Grep, Glob, etc.) instead of only firing when the main agent stops.

Evidence

When a hookify rule is configured with event: stop:

---
name: require-tests-before-stopping
enabled: true
event: stop
action: warn
conditions:
  - field: reason
    operator: regex_match
    pattern: .*
---

⚠️ **Test Verification Required**
...

The rule fires on PreToolUse and PostToolUse hooks for ALL tools:

Read(.claude/hookify.prevent-commenting-tests.local.md)
  ⎿  PreToolUse:Read says: **[require-tests-before-stopping]**
     ⚠️ **Test Verification Required**
     ...
  ⎿  PostToolUse:Read says: **[require-tests-before-stopping]**
     ⚠️ **Test Verification Required**
     ...

Root Cause

In hooks/pretooluse.py and hooks/posttooluse.py, when processing tools other than Bash/Edit/Write/MultiEdit, the code sets event=None:

tool_name = input_data.get('tool_name', '')

event = None
if tool_name == 'Bash':
    event = 'bash'
elif tool_name in ['Edit', 'Write', 'MultiEdit']:
    event = 'file'

# Load rules
rules = load_rules(event=event)  # ← Passing event=None!

When event=None, the filtering logic in core/config_loader.py doesn't run:

# Filter by event if specified
if event:  # ← This is False when event=None!
    if rule.event != 'all' and rule.event != event:
        continue

This causes all rules (including event: stop rules) to be loaded and evaluated for tools like Read, Grep, Glob.

Impact

  • event: stop rules spam warnings/blocks on every tool use
  • Users cannot create reliable "before stopping" checks
  • Hookify rules become unusable for completion verification workflows
  • Significant noise in the UI during normal operations

Steps to Reproduce

  1. Create .claude/hookify.test-stop.local.md:
---
name: test-stop-event
enabled: true
event: stop
action: warn
---

This should only appear on Stop events!
  1. Use any non-bash/non-file tool (Read, Grep, Glob)
  2. Observe the warning appears on PreToolUse and PostToolUse hooks

Fix

Add early exit in pretooluse.py and posttooluse.py when tool is not bash/file-related:

event = None
if tool_name == 'Bash':
    event = 'bash'
elif tool_name in ['Edit', 'Write', 'MultiEdit']:
    event = 'file'
else:
    # No relevant event for this tool - exit early
    # This prevents loading 'stop' and other non-tool-specific rules
    print(json.dumps({}), file=sys.stdout)
    sys.exit(0)

# Load rules
rules = load_rules(event=event)

This ensures that only bash and file rules are processed in PreToolUse/PostToolUse hooks, while stop rules are only processed by the dedicated stop.py hook.

Environment

  • Claude Code version: Latest
  • Hookify plugin version: 0.1.0
  • Platform: macOS (but affects all platforms)

Labels

  • bug
  • plugin
  • hookify

View original on GitHub ↗

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