ralph-wiggum stop hook silently stops loops on tool_use-only assistant messages
Bug Description
The ralph-wiggum plugin's stop-hook.sh silently kills self-referential loops when the assistant's last message contains only tool_use content blocks (no text blocks). This happens regularly during normal agentic usage — e.g., when Claude's final action in a turn is a TaskUpdate, Read, or Bash tool call with no accompanying text narration.
Root Cause
The stop hook extracts only the last JSONL line with role: assistant, filters for .type == "text" content blocks, and when none are found, treats it as "no content" and stops the loop by deleting the state file and exiting.
Affected code: plugins/ralph-wiggum/hooks/stop-hook.sh lines 80-112
Fix Already Exists
This exact bug was fixed in the sibling ralph-loop plugin in anthropics/claude-plugins-official:
adfc379— fix(ralph-loop): stop hook fails when last assistant block is tool_use8644df9— fix(ralph-loop): isolate loop state to the session that started it028eccf— address review: bound grep to tail -n 100; restore explicit error paths
The fix changes the hook to scan the last 100 assistant lines (not just the last 1), use jq -rs slurp mode, and treat empty text as "no promise tag found = continue loop" rather than "error = stop loop."
Impact
- Loops stop silently with no user-visible error
- Users cannot distinguish between a completed loop and a bug-killed loop
- Any non-trivial agentic loop that produces tool_use-only messages will hit this
- Tested and confirmed with 6 test cases (2 live tmux sessions, 4 direct hook tests)
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗