Skip to content

Fix: Hook commands fail - stdin JSON not parsed#1061

Open
thewoolleyman wants to merge 1 commit intoruvnet:mainfrom
thewoolleyman:fix/hooks-stdin-json-parsing
Open

Fix: Hook commands fail - stdin JSON not parsed#1061
thewoolleyman wants to merge 1 commit intoruvnet:mainfrom
thewoolleyman:fix/hooks-stdin-json-parsing

Conversation

@thewoolleyman
Copy link

Summary

All Claude Code hooks generated by claude-flow init fail silently because they reference shell environment variables ($TOOL_INPUT_file_path, $PROMPT, $TOOL_SUCCESS, etc.) that Claude Code never sets. Claude Code passes hook context as JSON via stdin, not as environment variables.

This causes errors like:

  • UserPromptSubmit hook error
  • PostToolUse:Bash hook error
  • PreToolUse:Edit hook error

Every hook that needs tool input data is affected.

Root Cause

The settings-generator.ts and static .claude/settings.json template generate hook commands like:

npx @claude-flow/cli@latest hooks pre-edit --file "$TOOL_INPUT_file_path"

But $TOOL_INPUT_file_path is never set. Claude Code actually pipes JSON to stdin:

{
  "hook_event_name": "PreToolUse",
  "tool_name": "Edit",
  "tool_input": { "file_path": "/path/to/file.ts" }
}

Fix

Introduces .claude/hooks/hook-bridge.sh, a bridge script that:

  1. Reads the stdin JSON from Claude Code
  2. Extracts relevant fields using jq
  3. Forwards them as proper CLI arguments

All hook commands now route through the bridge:

.claude/hooks/hook-bridge.sh pre-edit

Files changed

  • New: v3/@claude-flow/cli/.claude/hooks/hook-bridge.sh - Bridge script
  • Modified: v3/@claude-flow/cli/src/init/settings-generator.ts - Generator uses bridge
  • Modified: v3/@claude-flow/cli/src/init/executor.ts - Init copies bridge script
  • Modified: v3/@claude-flow/cli/.claude/settings.json - Static template uses bridge

Test plan

  • Verify echo '{"prompt":"test"}' | .claude/hooks/hook-bridge.sh route works
  • Verify echo '{"tool_input":{"file_path":"/tmp/test.ts"}}' | .claude/hooks/hook-bridge.sh pre-edit works
  • Verify echo '{}' | .claude/hooks/hook-bridge.sh pre-edit exits cleanly (no error)
  • Verify npx @claude-flow/cli@latest init --force creates .claude/hooks/hook-bridge.sh
  • Verify no more UserPromptSubmit hook error or PostToolUse:Bash hook error in Claude Code

Note

Requires jq to be installed. This is standard on macOS (via Xcode CLI tools) and most Linux distributions. Windows users need WSL or Git Bash (which was already effectively required by the existing bash-syntax hooks).

🤖 Generated with claude-flow

…stdin JSON

Claude Code passes hook context as JSON via stdin, not as shell environment
variables. All generated hook commands referenced nonexistent variables like
$TOOL_INPUT_file_path, $PROMPT, $TOOL_SUCCESS, etc., causing every hook
(PreToolUse, PostToolUse, UserPromptSubmit, SessionStart, Notification)
to silently fail with empty arguments.

The fix introduces .claude/hooks/hook-bridge.sh, a bridge script that reads
the stdin JSON with jq, extracts the relevant fields, and forwards them as
proper CLI arguments. All hook commands in settings.json and the
settings-generator now route through this bridge script.

Changes:
- Add .claude/hooks/hook-bridge.sh bridge script
- Update settings-generator.ts to emit bridge-based hook commands
- Update static .claude/settings.json template
- Update executor.ts to create .claude/hooks/ dir and copy bridge on init

Co-Authored-By: claude-flow <ruv@ruv.net>
@thewoolleyman
Copy link
Author

Human-generated comment:

After installing claude flow, and starting to use it via Claude Code, I kept getting warnings/errors like UserPromptSubmit hook error and PostToolUse:Bash hook error.

I asked Claude Flow to identify the fix, and it determined it was in the claude flow hooks. So I had it create this MR with the fix.

I'm not getting the errors anymore locally.

But this does introduce JQ as a dependency, so I don't know if that is a problem. If it is, I can try to have it updated to remove the JQ dependency.

Thanks...

thewoolleyman added a commit to thewoolleyman/home-tech-infrastructure that referenced this pull request Feb 1, 2026
Claude Code passes hook context as JSON via stdin, not as shell
environment variables. All hooks now use hook-bridge.sh which
reads stdin JSON with jq and forwards fields as CLI arguments.

Ref: ruvnet/claude-flow#1061

Co-Authored-By: claude-flow <ruv@ruv.net>
@nfl001
Copy link

nfl001 commented Feb 5, 2026

what OS and terminal do you use ? I'm having the same issue on windows terminal.

by adding bash -c in every hooks with the type "command" I've been able to resolve the issue without jq dependency

@thewoolleyman
Copy link
Author

what OS and terminal do you use ? I'm having the same issue on windows terminal.

by adding bash -c in every hooks with the type "command" I've been able to resolve the issue without jq dependency

I think this was on my Mac OS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants