Skip to content

fix(hookify): load only event:all rules for unknown tools, not all rules#68672

Closed
AZERDSQ131 wants to merge 2 commits into
anthropics:mainfrom
AZERDSQ131:fix/hookify-unknown-tool-event-fallback
Closed

fix(hookify): load only event:all rules for unknown tools, not all rules#68672
AZERDSQ131 wants to merge 2 commits into
anthropics:mainfrom
AZERDSQ131:fix/hookify-unknown-tool-event-fallback

Conversation

@AZERDSQ131

Copy link
Copy Markdown

Problem

In plugins/hookify/hooks/pretooluse.py and posttooluse.py, when tool_name is not Bash or Edit/Write/MultiEdit, the event variable is never assigned and remains None:

# before
event = None
if tool_name == 'Bash':
    event = 'bash'
elif tool_name in ['Edit', 'Write', 'MultiEdit']:
    event = 'file'
rules = load_rules(event=event)  # event=None → no filter applied

load_rules(event=None) skips all filtering and returns every enabled rule. This means rules declared event: bash (matching shell commands) or event: file (matching file content) are evaluated against Read, Glob, Task and other tools — producing false positives or unexpected blocks.

Fix

Add an explicit else branch that sets event = 'all'. Rules declared event: all are explicitly opt-in for all tools. Bash/file-specific rules are never reached for unknown tools.

# after
if tool_name == 'Bash':
    event = 'bash'
elif tool_name in ['Edit', 'Write', 'MultiEdit']:
    event = 'file'
else:
    event = 'all'
rules = load_rules(event=event)

Fix applied identically in both pretooluse.py and posttooluse.py.

🤖 Generated with Claude Code

…olUse block logic

A blocking rule in rule_engine.py returned permissionDecision:"deny" for
both PreToolUse and PostToolUse events. PostToolUse fires after the tool
has already executed; sending permissionDecision:"deny" has no effect and
produces undefined behaviour in the Claude Code hook protocol.

PreToolUse now returns the deny decision as before.
PostToolUse and all other non-Stop events fall through to the plain
systemMessage path, which is the only valid output format for post-execution
hooks.
…oading all rules

When tool_name was neither Bash nor Edit/Write/MultiEdit, the local
variable `event` remained None. Passing event=None to load_rules()
bypasses all filtering and returns every rule regardless of the event
field, including bash- and file-specific rules that were never intended
to run for tools like Read, Glob, or Task.

Add an explicit else branch: event = 'all'. Only rules declared with
event: all are now evaluated for unknown tools.
@AZERDSQ131

Copy link
Copy Markdown
Author

Closing: absorbed by #68673 which is a superset covering the same hookify files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant