Bug Report: PreToolUse Hooks Strip Result Data from AskUserQuestion Tool
Bug Report: PreToolUse Hooks Strip Result Data from AskUserQuestion Tool
Summary
When PreToolUse hooks are enabled in Claude Code settings, the AskUserQuestion tool fails to return the user's selected answer in the function results. The answer data is completely missing from the hook result, making it impossible to validate or use user responses. Disabling all PreToolUse hooks resolves the issue immediately.
Severity
Critical - Blocks all interactive workflows that depend on receiving user choices from AskUserQuestion tool.
Reproduction Steps
Step 1: Verify AskUserQuestion Works Without Hooks
- Set
"disableAllHooks": truein~/.claude/settings.json - Restart Claude Code
- Invoke AskUserQuestion tool with any question
-
Expected Result: Function returns
"User has answered your questions: \"<question>\"=\"<answer>\"" - Actual Result: ✅ Works correctly - answer data is present
Step 2: Enable PreToolUse Hooks and Reproduce Bug
- Set
"disableAllHooks": falsein~/.claude/settings.json - Restart Claude Code
- Invoke AskUserQuestion tool with the same question
-
Expected Result: Function returns
"User has answered your questions: \"<question>\"=\"<answer>\"" -
Actual Result: ✗ Bug reproduced - function returns
"User has answered your questions: ."(answer missing)
Step 3: Isolate Which Hook Type Causes Issue
Tested with PreToolUse hooks disabled and PostToolUse hooks enabled:
- Result: ✅ AskUserQuestion works correctly
- Conclusion: Bug is specifically in PreToolUse hook infrastructure
Step 4: Test Individual PreToolUse Hooks
Tested each of the three PreToolUse hooks individually:
-
task_required_skills_tracker.py- ✗ Causes bug -
prevent_skill_reinvocation.py- ✗ Causes bug -
gated_tool_access_control.py- ✗ Causes bug
Conclusion: All PreToolUse hooks cause the bug (not specific to one hook)
Root Cause Analysis
Evidence That Hooks Are Implemented Correctly
-
All three PreToolUse hooks use cchooks SDK properly
- They correctly call
context.output.allow()orcontext.output.deny() - They follow the documented PreToolUse hook pattern
- They output valid JSON with correct schema
- They correctly call
-
PreToolUse hooks execute and return properly
- Hook debug logs confirm hooks execute successfully
- Hooks return proper JSON decisions (allow/deny)
- Hooks don't crash or exit with errors
-
AskUserQuestion tool executes and returns result
- Tool runs without errors
- Tool produces a result object
- Result contains the user's selected answer
-
The answer data is lost between tool execution and function result
- When hooks disabled: Full answer data returned
- When hooks enabled: Answer data stripped
Root Cause Hypothesis
Claude Code's hook infrastructure has a bug when processing UI-only tools (like AskUserQuestion) in the presence of PreToolUse hooks. The most likely cause is:
Claude Code's internal hook result processing is not properly preserving tool response data for UI tools when PreToolUse hooks are active.
Possible mechanisms:
- Claude Code replaces UI tool results with hook responses instead of merging them
- The hook infrastructure has a special code path for UI tools that breaks with PreToolUse hooks
- Result data is stripped during hook response serialization for UI tools
- Hook output transformation doesn't account for UI tool response structures
Expected Behavior
When AskUserQuestion tool executes:
- PreToolUse hook executes and returns allow decision
- AskUserQuestion tool executes and returns user's selection
- Function result includes both the hook decision AND the tool result with answer data
- Answer data should be accessible in the function result
Actual Behavior
When AskUserQuestion tool executes:
- PreToolUse hook executes and returns allow decision ✓
- AskUserQuestion tool executes and returns user's selection ✓
- Function result only includes hook decision ✗
- Answer data is missing/stripped ✗
Impact
- Blocks: Any workflow using AskUserQuestion with PreToolUse hooks enabled
- Affects: All users with active PreToolUse hooks who need interactive tool responses
- Prevents: Validation of user choices, conditional logic based on selections, interactive task workflows
-
Workaround: Disable all hooks (
"disableAllHooks": true) - not acceptable for production use
Environment
- Claude Code Version: Latest (as of Nov 20, 2025)
- Model: claude-haiku-4-5-20251001
- Platform: Linux (Ubuntu)
-
Settings Location:
~/.claude/settings.json
Affected Code/Components
- Claude Code's PreToolUse hook infrastructure (internal, not cchooks SDK)
- Specifically: Hook result processing for UI-only tools
- Related: Hook result serialization/deserialization layer
Hook Configuration (Minimal Repro)
{
"disableAllHooks": false,
"hooks": {
"PreToolUse": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/production/any-pretooluse-hook.py"
}
]
}
]
}
}
Workaround
Temporary: Set "disableAllHooks": true in settings.json
- ⚠️ Not recommended for production (disables all safety hooks)
- ✅ Confirms bug is in hook infrastructure
- ⚠️ Removes all hook-based safety and guidance systems
Testing Notes
- Tested with 3 different PreToolUse hooks - all cause the bug
- Bug is 100% reproducible
- Bug appears immediately after restart with hooks enabled
- Bug disappears immediately when hooks disabled and restarted
- PostToolUse hooks do not cause the issue
- All other hook types do not cause the issue
Questions for Claude Code Team
- Is there special handling for UI-only tools in the PreToolUse hook infrastructure?
- Does the hook result processing preserve tool response data for UI tools?
- Is there a serialization/deserialization issue with UI tool responses when PreToolUse hooks are active?
- Should UI tools (like AskUserQuestion) be excluded from PreToolUse hook processing?
Related Files for Investigation
- Claude Code's internal hook result processing (not public)
- Hook infrastructure response handling for UI tools
- AskUserQuestion tool implementation's integration with hook system
- PreToolUse hook decision handling for non-state-modifying tools
Resolution Suggestions
- Preserve UI tool results in PreToolUse hook infrastructure: Ensure that when PreToolUse hooks return an allow decision, the original tool result data (including UI tool responses) is preserved and merged with the hook response
- Special handling for UI-only tools: Consider excluding UI-only tools from PreToolUse hook processing, or have a special code path that always preserves tool result data
- Validation in hook SDK: Consider adding validation in cchooks SDK to warn developers if PreToolUse hooks are used with UI tools
Reproduction Code
# Test case to reproduce the bug
from cchooks import AskUserQuestion
def test_asksuser_question_with_pretooluse_hooks():
"""
Setup:
1. Enable PreToolUse hooks in settings.json
2. Restart Claude Code
3. Run this code:
"""
result = AskUserQuestion(
questions=[{
"question": "Is Python a programming language?",
"header": "Test",
"options": [
{"label": "True", "description": "Correct"},
{"label": "False", "description": "Incorrect"}
],
"multiSelect": False
}]
)
# Expected: result contains answer data like:
# {"User has answered your questions: \"Is Python a programming language?\"=\"True\""}
# Actual (with hooks enabled): result is:
# {"User has answered your questions: ."}
assert "True" in str(result), "Answer data missing - BUG CONFIRMED"
Additional Context
Testing Matrix
| Scenario | AskUserQuestion Returns Answer | Works |
|---|---|---|
| All hooks disabled | ✅ Yes | ✅ YES |
| PostToolUse only | ✅ Yes | ✅ YES |
| SessionStart only | ✅ Yes | ✅ YES |
| PreToolUse only | ❌ No | ❌ NO |
| PreToolUse + PostToolUse | ❌ No | ❌ NO |
| PreToolUse + SessionStart | ❌ No | ❌ NO |
Debug Evidence
Hook debug logs confirm:
- PreToolUse hooks execute successfully
- Hooks return valid JSON responses
- No errors in hook processing
- Tool execution appears to complete
- Answer data is lost between tool execution and function result return
Code Quality
- All hooks follow cchooks SDK best practices
- All hooks use proper error handling
- All hooks return valid JSON
- Issue is NOT in hook implementation
- Issue is in Claude Code's hook infrastructure
Submitted by: Christina Date: November 20, 2025 Reproducibility: 100% - Consistent and immediate
This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.
Yes this issue is still occurring