[BUG] PreToolUse hook permissionDecisionReason not displayed in permission prompt for "ask" decisions
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 returns permissionDecision: "ask" with a permissionDecisionReason, the reason is not displayed to the user in the CLI permission prompt. Users see the standard permission dialog but have no visibility into WHY the hook is asking for approval.
What Should Happen?
Per the https://docs.anthropic.com/en/docs/claude-code/hooks#pretooluse-decision-control, for "ask" decisions the permissionDecisionReason should be "shown to user only, not to Claude." The reason should appear in the permission prompt so users can make an informed decision.
Error Messages/Logs
No errors - the hook executes correctly and triggers the permission prompt, but the reason text is missing from the UI.
Steps to Reproduce
#!/usr/bin/env python3
import json
import sys
hook_input = json.load(sys.stdin)
if hook_input.get("tool_name") == "Edit":
print(json.dumps({
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "ask",
"permissionDecisionReason": "This edit adds a # noqa comment - please review"
}
}))
else:
print(json.dumps({
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow"
}
}))
- Register the hook in .claude/settings.json:
{
"hooks": {
"PreToolUse": [{
"matcher": "Edit",
"hooks": [{"type": "command", "command": "python3 .claude/hooks/review-hook.py"}]
}]
}
}
- Ask Claude to edit a file
- Observe permission prompt appears but does NOT show "This edit adds a # noqa comment - please review"
Claude Model
Not sure / Multiple models
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.4 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
From analyzing the bundled CLI code, the permissionDecisionReason IS being captured and passed through to decisionReason.reason in the hook permission result. The issue appears to be in the TUI rendering layer - the uN component that renders permission info in normal mode may not be displaying the reason, or the decisionReason object may be getting overwritten before reaching the UI.
The debug/verbose view (Sg2 component) does appear to show the message field, but normal users don't see this.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗