[FEATURE REQUEST] PreToolUse Hook should be able to modify tool inputs
Summary
PreToolUse hooks can successfully process and modify tool input JSON, but the modified commands are not executed. Instead, Claude Code continues to execute the original unmodified command.
Environment
- Claude Code Version: v1.0.43
- Platform: macOS (Darwin 24.5.0)
- Hook Type: PreToolUse
- Tool: Bash
Expected Behavior
When a PreToolUse hook modifies the tool_input.command field and returns {"decision": "approve"}, Claude Code should execute the modified command.
Actual Behavior
Claude Code executes the original command, ignoring modifications made by the hook.
Reproduction Steps
- Create hook configuration in
.claude/settings.local.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "jq '.tool_input.command = \"ANTHROPIC_API_KEY='$ANTHROPIC_API_TEST_KEY' \" + .tool_input.command | .decision = \"approve\"'"
}
]
}
]
}
}
- Set environment variable in global
~/.claude/settings.json:
{
"env": {
"ANTHROPIC_API_TEST_KEY": "test-key-value"
}
}
- Create test file
example/hook_test.dart:
import 'dart:io';
void main() {
print('ANTHROPIC_API_KEY.length: ${Platform.environment['ANTHROPIC_API_KEY']?.length ?? 0}');
print('ANTHROPIC_API_TEST_KEY.length: ${Platform.environment['ANTHROPIC_API_TEST_KEY']?.length ?? 0}');
}
- Run command:
dart run example/hook_test.dart
- Observe output:
ANTHROPIC_API_KEY.length: 0 // Should be 108 if hook worked
ANTHROPIC_API_TEST_KEY.length: 108 // Confirms env var is available
Verification that Hook Logic Works
Manual simulation of hook command:
echo '{"tool_input": {"command": "dart run example/hook_test.dart"}}' | jq '.tool_input.command = "ANTHROPIC_API_KEY='$ANTHROPIC_API_TEST_KEY' " + .tool_input.command | .decision = "approve"'
Output:
{
"tool_input": {
"command": "ANTHROPIC_API_KEY=sk-ant-api03-... dart run example/hook_test.dart"
},
"decision": "approve"
}
Manual execution of modified command:
ANTHROPIC_API_KEY=sk-ant-api03-... dart run example/hook_test.dart
Output:
ANTHROPIC_API_KEY.length: 108 // ✅ Works when run manually
ANTHROPIC_API_TEST_KEY.length: 108
Additional Evidence
- Hook is triggered: Confirmed by testing with deny hooks that successfully block commands
- Environment variables available:
ANTHROPIC_API_TEST_KEYis accessible within hook context - Hook processes JSON correctly: Manual testing shows jq command works perfectly
- Modified command works: Manual execution with injected environment variable succeeds
Impact
This prevents users from using hooks to inject environment variables, credentials, or other command modifications that are essential for many workflows.
Workaround
None available. Manual command execution works, but automated injection via hooks fails.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗