CLI: permissionDecisionReason not displayed in permission prompt for PreToolUse 'ask' decisions
Description
When a PreToolUse hook returns permissionDecision: "ask", the permissionDecisionReason field is not displayed to users in the CLI permission prompt. Users see the standard permission dialog but cannot see WHY the hook is asking for approval.
Expected Behavior
According to the hooks documentation, for "ask" decisions the permissionDecisionReason should be "shown to user only, not to Claude."
The reason should be visible in the permission prompt so users understand why they're being asked for approval.
Actual Behavior
The permission prompt appears but does not display the permissionDecisionReason or systemMessage fields. Users have no visibility into why the hook triggered the ask.
Reproduction Steps
- Create a PreToolUse hook that returns an "ask" decision:
import json
import sys
def main():
hook_input = json.load(sys.stdin)
tool_name = hook_input.get("tool_name", "")
if tool_name == "Edit":
output = {
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "ask",
"permissionDecisionReason": "This is the reason that should be shown to the user",
"systemMessage": "WARNING: Custom message here"
}
}
print(json.dumps(output))
return 0
# Allow other tools
output = {
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow",
"permissionDecisionReason": "Allowed"
}
}
print(json.dumps(output))
return 0
if __name__ == "__main__":
sys.exit(main())
- Register the hook in
.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit",
"hooks": [
{
"type": "command",
"command": "python .claude/hooks/test-hook.py"
}
]
}
]
}
}
- Ask Claude to edit a file
- Observe that the permission prompt appears but does not show the reason
Environment
- Claude Code CLI (not VS Code extension)
- Linux (WSL2)
Additional Context
The hook JSON output is correct (verified by running manually):
{"hookSpecificOutput": {"hookEventName": "PreToolUse", "permissionDecision": "ask", "permissionDecisionReason": "Suppression comment detected...", "systemMessage": "SUPPRESSION COMMENT: noqa (ruff/flake8)"}}
The hook correctly triggers the "ask" behavior (permission is requested), but the reason is not visible to help users make an informed decision.
Use Case
This is important for hooks that enforce code quality policies. For example, a hook that detects linter suppression comments (# noqa, # type: ignore) and requires approval - users need to see WHY they're being asked to approve the edit.
This issue has 9 comments on GitHub. Read the full discussion on GitHub ↗