PostToolUse Hooks Not Executing Despite Correct stdin JSON Configuration - Comprehensive Testing Report
Bug Report: PostToolUse Hooks Completely Non-Functional
Environment
- Claude Code Version: 1.0.89
- Platform: macOS Darwin 24.6.0
- Session Type: CLI
- Date: August 23, 2025
Summary
PostToolUse hooks do not execute at all when tools are used, despite following documentation exactly and hooks working perfectly when called manually.
Comprehensive Testing Performed
1. Created Multiple Test Hooks
Simple Test Hook (~/.claude/hooks/simple-test.sh):
#!/bin/bash
echo "HOOK RAN" > /tmp/simple_hook_test.txt
exit 0
stdin JSON Hook (per documentation):
#!/bin/bash
JSON_INPUT=$(cat)
FILE_PATH=$(echo "$JSON_INPUT" | jq -r '.tool_input.file_path // empty')
echo "Hook executed for: $FILE_PATH" >> /tmp/hook_test.log
Markdown Auto-Fix Hook:
#!/bin/bash
JSON_INPUT=$(cat)
FILE_PATH=$(echo "$JSON_INPUT" | jq -r '.tool_input.file_path // empty')
if [[ "$FILE_PATH" == *.md ]]; then
# Fix code blocks without language
awk '/^```$/ { print "```text"; next } { print }' "$FILE_PATH" > temp
mv temp "$FILE_PATH"
# Run markdownlint fixes
markdownlint-cli2 --config ~/.markdownlint.json --fix "$FILE_PATH"
echo "✓ Fixed markdown formatting in $FILE_PATH"
fi
2. Configuration in settings.json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit|MultiEdit",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/markdown-auto-fix.sh"
}
]
}
]
}
}
3. Test Results
Manual Execution: ✅ WORKS PERFECTLY
# Test with JSON input as per documentation
echo '{"tool_input": {"file_path": "/tmp/test.md"}}' | ~/.claude/hooks/markdown-auto-fix.sh
# Output: ✓ Fixed markdown formatting in /tmp/test.md
# Result: File is properly formatted, all linting errors fixed
Automatic Execution via Claude Code: ❌ NEVER EXECUTES
- Created dozens of markdown files with linting errors
- Hook never executes
- No log files created
- No output shown
- Files remain unfixed
4. Verification Steps Taken
- Permissions: All hooks have 755 permissions
- JSON Validity: Verified with
jq . settings.json - Path Testing: Tested absolute paths, relative paths
- Matcher Testing: Tried "*", "Write", "Edit", combinations
- Session Restarts: Restarted sessions 20+ times
- /hooks Command: Used multiple times - shows hooks but they don't execute
- Environment Variables: Checked $CLAUDE_TOOL_NAME, $CLAUDE_TOOL_PARAMS - empty
- stdin Testing: Confirmed hooks read stdin correctly when called manually
- Multiple Locations: Tested writing to /tmp, home directory, project directories
Test Files Created
Multiple test markdown files were created through Claude Code Write tool with various linting errors that the hooks should have fixed:
Common errors in test files:
- MD040: Code blocks without language specifier
- MD032: Missing blank lines around lists
- MD031: Missing blank lines around code blocks
- MD022: Missing blank lines around headings
- MD047: Missing newline at end of file
Evidence of Hook System Being Broken
- Hook scripts work: When executed manually with proper JSON input, they fix all issues
- Configuration is correct: Following documentation exactly, JSON is valid
- Trigger mechanism broken: Claude Code never calls the hooks when tools are used
- No error messages: Silent failure with no indication why
- Multiple sessions affected: Issue persists across different Claude sessions
Impact
This bug makes the entire hooks feature unusable for its primary purposes:
- Automatic code formatting
- Markdown linting
- Security scanning
- Custom workflows
- File validation
Users must manually run formatters/linters after every file creation/edit, defeating the purpose of hooks.
Expected Behavior
PostToolUse hooks should execute after Write/Edit/MultiEdit operations and process files automatically.
Actual Behavior
Hooks never execute. No logs, no output, no file modifications - complete silence.
Workaround Created
Had to create a manual command that users must run manually after creating markdown files:
#!/bin/bash
# Manual markdown fix since hooks don't work
markdownlint-cli2 --config ~/.markdownlint.json --fix "$1"
python3 -m mdformat --wrap 120 "$1"
Conclusion
The PostToolUse hook system is completely non-functional. The infrastructure exists (hooks can be called manually) but the trigger mechanism that should invoke hooks when tools are used is broken. This is a critical bug affecting a core advertised feature of Claude Code.
Related Issues
- #6305 - Similar reports of hooks not executing
- #2891 - Hooks not executing despite following documentation
- #5093 - Hooks configured but not executing
Please prioritize fixing this as it severely impacts developer productivity and makes Claude Code less useful for automated workflows.
This issue has 7 comments on GitHub. Read the full discussion on GitHub ↗