[Bug] Plugin hooks JSON output not captured
Bug Description
Plugin hooks execute successfully but their JSON output is not captured/parsed by Claude Code. Identical hook files work correctly as inline hooks in settings.json.
Root Cause
Stop Plugin hooks' STDOUT is not being captured by Claude Code. The Stop hook executes, generates valid JSON output, but Claude Code skips the output parsing step entirely and jumps directly to checking for async responses.
Evidence from Debug Logs
Working case (inline hook in settings.json) - Lines 236-242:
[DEBUG] Getting matching hook commands for Stop with query: undefined
[DEBUG] Found 1 hook matchers in settings
[DEBUG] Matched 1 unique hooks for query "no match query" (1 before deduplication)
[DEBUG] Hooks: Checking initial response for async: {"continue":true,"stopReason":"","suppressOutput":true}
[DEBUG] Hooks: Parsed initial response: {"continue":true,"stopReason":"","suppressOutput":true}
[DEBUG] Hooks: Initial response is not async, continuing normal processing
[DEBUG] Successfully parsed and validated hook JSON output
**Broken case (plugin hook from plugins//hooks/ directory) - Lines 1720-1726:*
[DEBUG] Getting matching hook commands for Stop with query: undefined
[DEBUG] Found 1 hook matchers in settings
[DEBUG] Matched 1 unique hooks for query "no match query" (1 before deduplication)
[DEBUG] Hooks: getAsyncHookResponseAttachments called
[DEBUG] Hooks: checkForNewResponses called
[DEBUG] Hooks: Found 0 total hooks in registry
[DEBUG] Hooks: checkForNewResponses returning 0 responses
Key difference: Plugin hooks skip from "Matched 1 unique hooks" directly to "getAsyncHookResponseAttachments" with:
- NO "Checking initial response" line
- NO "Successfully parsed" line
Verification
Hook files are byte-for-byte identical (MD5 verified):
- Both output valid JSON when tested manually via CLI
- Both execute successfully (confirmed in hook log files)
- Both load all dependencies correctly
Hypothesis
Plugin hook STDOUT is either:
- Not being captured by Claude Code's hook execution system
- Being redirected/piped incorrectly
- Being buffered and not flushed before process exit
The issue is specifically in how Claude Code invokes/captures output from plugin hooks vs inline hooks.
Impact
Plugin-based hooks may execute their logic but sometimes fail to influence Claude Code behavior because their output never reaches the hook processor.
Environment:
- Platform: darwin
- Terminal: ghostty
- Version: 2.0.31
- Feedback ID: 58c126bf-37b7-4403-a4d0-c9abe17ad27e
This issue has 15 comments on GitHub. Read the full discussion on GitHub ↗