[BUG] ralph-loop Stop hook silently fails on Windows after Claude Code 2.1.126 (worked on 2.1.119)
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
The ralph-loop plugin Stop hook fires correctly on Claude Code 2.1.119 but silently fails to fire on Claude Code 2.1.126 (Windows + Git Bash).
The hook script itself is valid — when invoked manually it returns the correct decision: block JSON. But Claude Code 2.1.126 doesn't appear to invoke it
at end-of-turn anymore.
This effectively kills the plugin on the latest Windows builds — the loop runs exactly 1 iteration and goes idle waiting for a hook that never fires.
### Evidence — same machine, same plugin, only Claude Code version differs
Counted hook execution events (type:"attachment" + attachment.type:"hook_system_message" + hookEvent:"Stop") across JSONL transcripts:
| Session | CC version | Hook events | Outcome |
|---|---|---|---|
| atlas, 2026-04-30 | 2.1.119 | 175 | Loop ran for hours, completed normally |
| atlas, 2026-05-02 | 2.1.119 | 51 | Loop ran 17 iters, completed |
| atlas, 2026-04-30 (other) | 2.1.119 | 7 | Worked |
| guberman3, 2026-05-04 | 2.1.126 | 0 | Stopped after iter 1 |
| guberman3, 2026-05-04 (other) | 2.1.126 | 0 | Stopped after iter 1 |
The session that broke shows the agent ending iter 1 normally, then nothing:
15:52:19.316UTC — assistant text "Iter 1 done — commit f7066f9"15:52:19.393UTC —system/turn_durationevent (turn ended)15:55:22.817UTC —system/away_summaryevent (3 min later, session went idle)- No
hook_system_messageevent between turn end and away - No
decision:"block"reinjection - 18 minutes of idle until the user typed "continue manually"
### Manual hook invocation works fine
Running stop-hook.sh directly with simulated stdin input returns the correct JSON:
``json``
{
"decision": "block",
"reason": "<original prompt>",
"systemMessage": "🔄 Ralph iteration 2 | To stop: output <promise>DONE</promise>..."
}
The iteration: field in .claude/ralph-loop.local.md increments correctly. So the script is healthy — Claude Code 2.1.126 just isn't dispatching the
Stop event to it on Windows builds.
### What I ruled out
- Not the known bugs from issue #394 — no
cdin agent commands; state file not deleted; relative path resolves correctly because cwd stayed at project
root throughout the run
- Not a missing utility —
bash,jq,perl,sed,awk,grep,catall present in Git Bash 2.49 - Not
away_summaryitself — sessions on 2.1.119 also producedaway_summaryevents alongside hook events (10away_summaryin one atlas session,
coexisting with 175 hook events)
- Not lifecycle/permissions/settings — same
~/.claude/settings.jsonfor both working (atlas, 2.1.119) and broken (guberman3, 2.1.126) sessions
### About me
I'm a software engineer building agent systems on Claude Code. Happy to provide more JSONL artifacts, transcripts, or repro environment if useful for
triage.
What Should Happen?
After the agent ends a turn while a ralph-loop.local.md state file is active in the project root:
- Claude Code dispatches the Stop event to registered plugin hooks
- The plugin's
stop-hook.shscript executes with the standard stdin payload (session_id,transcript_path) - The script reads the state file, validates
iteration < max_iterations, checks the last assistant message for<promise>COMPLETION_PROMISE</promise>,
and either:
- Allows exit if
max_iterationsreached or completion promise emitted, OR - Returns
{"decision": "block", "reason": "<original prompt>", "systemMessage": "🔄 Ralph iteration N..."}to re-feed the original prompt and
increment the iteration counter
- Claude Code re-injects the
reasonfield as a new user message, surfaces thesystemMessageto the user, and the agent proceeds with iter N+1
This is the documented behavior of the plugin and matches what was observed on Claude Code 2.1.119, where a single overnight session produced 175
hook events (one per Stop), allowing the loop to run continuously for hours.
On Claude Code 2.1.126, none of the above happens — hook_system_message events are entirely absent from the JSONL transcript, even though the state
file is present, the script is executable, and manual invocation produces the correct output.
### Suggestions
- If
/loopdynamic mode +ScheduleWakeupis the intended successor (it's a great design — works without bash, context accumulates,
Anthropic-maintained), consider deprecating ralph-loop officially in the plugin README with a migration note pointing at /loop. The plugin still
installs and runs setup successfully, which misleads users into thinking the issue is their setup.
- If
ralph-loopis meant to keep working, investigate why the Stop event isn't dispatched to plugin hooks on Claude Code 2.1.126 Windows builds.
Possible angles: change in event lifecycle around away_summary, change in plugin hook registration timing, change in how Stop fires when
bypassPermissions mode is active.
- Either way, surface a clear log/error when a hook is registered but not invoked — silent failure is the worst-case UX. A debug log entry like `[hook]
Stop event fired, dispatching to plugin X` would have made this trivially diagnosable.
Error Messages/Logs
Steps to Reproduce
Environment
- OS: Windows 11 Home Single Language 10.0.26200
- Shell: PowerShell + Git Bash 2.49
- Claude Code (broken): 2.1.126 (native Windows installer, single binary at
~/.local/bin/claude.exe) - Claude Code (works): 2.1.119 (same machine, same plugin, prior version)
- Plugin:
ralph-loop@1.0.0fromclaude-plugins-official - Plan: Max
~/.claude/settings.jsonexcerpt:
``json``
{
"model": "opus[1m]",
"permissions": { "defaultMode": "bypassPermissions" },
"alwaysThinkingEnabled": true,
"skipDangerousModePermissionPrompt": true
}
### Reproduction steps
- Install Claude Code 2.1.126 for Windows (native installer)
- Install Git for Windows (provides Git Bash with
bash/jq/perl/sed/awk/grep) - Install the plugin:
````
claude plugin install ralph-loop@claude-plugins-official
- Confirm install:
```
claude plugin list
ralph-loop@claude-plugins-official Version: 1.0.0 Status: ✔ enabled`
Expect:
- Create a test git project:
``bash``
mkdir test-ralph && cd test-ralph
git init
echo "iter 0" > log.md
git add log.md && git commit -m "init"
- Start Claude Code in that directory and run:
````
/ralph-loop:ralph-loop "Append 'iter N done' to log.md, commit, then end your turn." --max-iterations 5 --completion-promise "ALL_DONE"
- Observed: agent appends iter 1, commits, ends turn. Session goes idle. After ~3 min,
system/away_summaryappears in the JSONL transcript. **No
further iterations occur.** Loop is dead.
- Verify the hook script itself works (proves the script is healthy, the issue is dispatch):
``bash`
# In Git Bash, from the project root:
echo '{"session_id":"<paste from JSONL>","transcript_path":"<paste path to current session JSONL>"}' \
| bash "$HOME/.claude/plugins/marketplaces/claude-plugins-official/plugins/ralph-loop/hooks/stop-hook.sh"
"decision":"block"
Expected: returns valid JSON with and the prompt re-fed in reason`.
Actual: returns valid JSON correctly. So the script works — Claude Code just isn't calling it.
- Compare to working version (if you have access to 2.1.119):
- Same project, same plugin, same
.claude/ralph-loop.local.md - Run the same
/ralph-loop:ralph-loopcommand - Hook fires after each turn;
hook_system_messageevents appear in JSONL; loop iterates correctly
### Files to inspect
~/.claude/projects/<encoded-cwd>/<session-id>.jsonl— transcript. Search forhook_system_message(zero matches on 2.1.126 broken sessions; many on
2.1.119 working sessions).
~/.claude/plugins/marketplaces/claude-plugins-official/plugins/ralph-loop/hooks/stop-hook.sh— the script that should be invoked but isn't.<project>/.claude/ralph-loop.local.md— state file. Verifyiteration:stays at 1 (not incremented) andsession_id:may be empty if
CLAUDE_CODE_SESSION_ID env var isn't set during setup.
Claude Model
Opus
Is this a regression?
Yes, this worked in a previous version
Last Working Version
2.1.119
Claude Code Version
2.1.126
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
PowerShell
Additional Information
_No response_
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗