PostToolUse hooks don't execute for failed Bash commands
Summary
PostToolUse hooks configured to monitor Bash tool execution are skipped entirely when the Bash command fails (exits with non-zero status). This limitation prevents hooks from providing useful feedback or context about failed commands.
Expected Behavior
PostToolUse hooks should execute regardless of whether the underlying tool call succeeds or fails, allowing hooks to:
- Provide additional context for failures
- Log failed operations
- Suggest remediation steps
- Perform cleanup after failed commands
Actual Behavior
PostToolUse hooks are completely skipped when Bash commands fail, as evidenced by the absence of hook execution debug output.
Reproduction Steps
- Configure a PostToolUse hook for Bash in settings.json:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/path/to/test-hook.sh"
}
]
}
]
}
}
- Create a simple test hook script:
#!/bin/bash
echo "PostToolUse hook executed" >&2
exit 0
- Run Claude Code with debug mode:
claude --debug
- Test with successful Bash command:
ls # This will show PostToolUse hook execution in debug output
- Test with failing Bash command:
ls nonexistent-file.txt # This will NOT show PostToolUse hook execution
Debug Output Evidence
Successful command (ls) shows PostToolUse hooks executing:
[DEBUG] Executing hooks for PostToolUse:Bash
[DEBUG] Getting matching hook commands for PostToolUse with query: Bash
[DEBUG] Found 1 hook matchers in settings
[DEBUG] Matched 1 unique hooks for query "Bash" (1 before deduplication)
[DEBUG] Found 1 hook commands to execute
[DEBUG] Executing hook command: /path/to/hook.sh with timeout 60000ms
[DEBUG] Hook command completed with status 0
Failed command (ls nonexistent-file.txt) shows NO PostToolUse hook execution:
[DEBUG] Bash tool invoked with command: ls nonexistent-file.txt
● Bash(ls nonexistent-file.txt)
⎿ Error: ls: cannot access 'nonexistent-file.txt': No such file or directory
[DEBUG] MCP server "ide": Calling MCP tool: getDiagnostics
# Notice: No PostToolUse hook debug output at all
Workaround
The only current workaround is to use commands that don't fail but simulate the failure output:
echo "Error: ls: cannot access 'test': No such file or directory"
# This successfully triggers PostToolUse hooks because exit code = 0
Use Case Impact
This limitation significantly impacts useful hook scenarios such as:
- Directory context hooks: Providing current working directory when "No such file or directory" errors occur
- Command validation: Logging or analyzing failed operations
- Error enhancement: Adding contextual information to help debug failures
- Cleanup operations: Performing cleanup after failed commands
Environment
- Claude Code version: Latest (as of 2025-01-22)
- OS: Linux (WSL2)
- Hook configuration: PostToolUse with Bash matcher
Documentation Impact
The hooks reference documentation doesn't mention this limitation. It should clarify whether PostToolUse hooks are intended to skip failed tool calls or if this is a bug.
Request
Please either:
- Fix the behavior so PostToolUse hooks execute for failed tool calls, OR
- Document this limitation clearly in the hooks reference documentation, OR
- Provide an alternative hook event that triggers for failed tool calls (e.g.,
PostToolFailure)
This issue has 9 comments on GitHub. Read the full discussion on GitHub ↗