[BUG] Notification hook only fires inconsistently (~25%) for permission prompts
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
The Notification hook is configured to trigger when Claude needs permission to use a tool (as documented). However, it only fires for approximately 25% of permission prompts during a session, with no clear pattern determining when it will or won't fire.
During testing with claude --debug, out of 13+ permission prompts, the Notification hook only fired 4 times (~30% success rate). The Stop hook works 100% reliably in the same session, proving hooks are loaded correctly.
The issue is in Claude Code's internal logic for when to check for Notification hooks - sometimes it checks immediately after permission prompts, sometimes it skips the check entirely.
What Should Happen?
According to the hooks documentation, the Notification hook should fire consistently when "Claude needs permission to use a tool". The hook should execute for every permission prompt, not just ~25% of them.
Error Messages/Logs
SUCCESSFUL Notification hook execution (from debug log lines 507-510):
[DEBUG] Getting matching hook commands for Notification with query: undefined
[DEBUG] Found 2 hook matchers in settings
[DEBUG] Matched 1 unique hooks for query "no match query" (2 before deduplication)
[DEBUG] Notification [paplay /usr/share/sounds/card_shuffle.wav 2>/dev/null || echo -e '\a'] completed with status 0
FAILED case (line 577) - No Notification hook check appears:
[DEBUG] Permission suggestions for Bash: [
{
"type": "addRules",
...
}
]
[DEBUG] AutoUpdaterWrapper: Installation type: native, using native: true
[DEBUG] Writing to temp file: ~/.claude.json.tmp...
(No Notification hook check at all)
Stop hook (ALWAYS successful, e.g., line 294):
[DEBUG] Executing hooks for Stop
[DEBUG] Getting matching hook commands for Stop with query: undefined
[DEBUG] Found 2 hook matchers in settings
[DEBUG] Matched 1 unique hooks for query "no match query" (2 before deduplication)
[DEBUG] Found 1 hook commands to execute
[DEBUG] Executing hook command: mpv /usr/share/sounds/card_shuffle.wav...
[DEBUG] Hook command completed with status 0
Analysis:
- Permission prompts WITHOUT Notification check: Lines 194, 577, 697, 723, 848, 1034, 1060, 1089
- Permission prompts WITH Notification check: Lines 493, 983, 1251, 1377
Steps to Reproduce
Steps to Reproduce
- Configure Notification hook in
~/.claude/settings.json:
``json``
{
"hooks": {
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "mpv /usr/share/sounds/card_shuffle.wav 2>/dev/null || echo -e '\\a'"
}
]
}
],
"Notification": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "paplay /usr/share/sounds/card_shuffle.wav 2>/dev/null || echo -e '\\a'"
}
]
}
]
}
}
- Start Claude Code with
claude --debug
- Interact with Claude to trigger multiple permission prompts:
- Try to read files outside approved directories
- Run unapproved bash commands (curl, wget, rm, etc.)
- Request access to various tools
- Observe debug logs:
tail -f ~/.claude/debug/latest
- Search for patterns:
grep "Permission suggestions" ~/.claude/debug/latest(should find 13+)grep "Notification.*completed" ~/.claude/debug/latest(only finds 4)
- Notice Notification hook only fires for a subset of permission prompts, while Stop hook fires 100% of the time
Claude Model
Sonnet (default)
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.0.15
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
WSL (Windows Subsystem for Linux)
Additional Information
- Hooks are loaded correctly: When Stop hook executes, debug shows "Found 2 hook matchers" (Stop + Notification)
- Notification execution works when checked: All 4 times the Notification hook was checked, it executed successfully with status 0
- The problem is inconsistent checking: Claude Code doesn't consistently check for Notification hooks after permission prompts
- No pattern identified: Tested various permission types (addRules, addDirectories, setMode combinations) - no clear pattern for when it fires
Configuration Context:
- Hooks in
~/.claude/settings.json(symlinked from~/dotfiles/.claude/settings.json) - Both Stop and Notification hooks use similar audio playback commands
- Stop hook uses
mpv, Notification hook usespaplay(both work when executed)
Impact:
This makes the Notification hook unreliable for its intended use case of alerting users when Claude needs permission. Users cannot depend on receiving consistent audio/visual notifications for approval requests.
Documentation Reference:
https://docs.claude.com/en/docs/claude-code/hooks states Notification triggers when "Claude needs permission to use a tool"
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗