[BUG] PreToolUse hook systemMessage not visible to Claude (assistant) when blocking
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?
When a PreToolUse hook blocks an operation and returns a systemMessage with a detailed error explanation, the user sees the message in the UI, but Claude (the assistant) only sees "Blocked by hook" - not the actual systemMessage content.
This makes it impossible for Claude to understand WHY a tool was blocked and self-correct. The assistant has to guess or ask the user to copy-paste the error message.
What Should Happen?
The systemMessage returned by the hook should be included in the <system-reminder> that Claude receives after a block, like:
<system-reminder>
PreToolUse:Bash hook blocked this operation:
**[commit-message-format]**
Invalid commit message format
All commits must follow: CRE-X (type): description
The `(type):` part is REQUIRED.
</system-reminder>
Instead, Claude only sees:
<system-reminder>
PreToolUse:Bash hook blocking error from command: "python3 .../hooks/pretooluse.py": Blocked by hook
</system-reminder>
Technical Details
The hook correctly returns:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny"
},
"systemMessage": "**[commit-message-format]**\n Invalid commit message...(detailed message)"
}
The systemMessage is surfaced to the user in the TUI, but NOT to the assistant in the system-reminder.
Why This Matters
- Self-correction: Claude can't fix issues if it doesn't know what's wrong
- Workflow efficiency: User has to manually explain what the hook said
- Plugin ecosystem: Hook authors expect
systemMessageto guide Claude's behavior
Related Issues
- #10062 -
permissionDecisionReasonnot surfaced (closed as dup, not fixed) - #9630 - Block reason not shown in
-pmode (different case) - #16289 -
systemMessagenot displayed for SubagentStop (same root cause)
Steps to Reproduce
- Create a PreToolUse hook that returns
systemMessageon deny (e.g., using hookify plugin) - Trigger the hook (e.g., run a git commit with wrong format)
- Observe: User sees the detailed message, Claude only sees "Blocked by hook"
Claude Code Version
Latest (2.x)
Platform
Linux (WSL2)
Operating System
Linux
Terminal/Shell
zsh
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗