[BUG] Plugins with .sh scripts break on Windows due to CRLF line endings from git clone
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?
Plugins that include .sh shell scripts (hooks, command templates, skill scripts) fail on Windows with "No such file or directory" errors. This affects multiple official and third-party plugins out of the box.
The root cause is that when the plugin installer clones repos on Windows, Git's default core.autocrlf=true converts LF to CRLF in .sh files. This turns the shebang #!/bin/bash into #!/bin/bash\r, making the script unexecutable. Additionally, the hook system uses /bin/bash which may resolve to WSL bash instead of Git Bash, and WSL bash cannot resolve Windows-style C:/ paths.
What Should Happen?
Plugins with .sh scripts should work immediately after installation on Windows without any manual fixes. The plugin installer should ensure .sh files have LF line endings regardless of the user's Git autocrlf setting.
Error Messages/Logs
Stop hook error: Failed with non-blocking status code: /bin/bash:
C:/Users/<username>/.claude/plugins/cache/claude-plugins-official/ralph-loop/<version>/hooks/stop-hook.sh: No such file or directory
Error: Bash command failed for pattern "!
"C:/Users/<username>/.claude/plugins/cache/claude-plugins-official/ralph-loop/<version>/scripts/setup-ralph-loop.sh" Build something --max-iterations 20 --completion-promise "DONE" ":
Steps to Reproduce
- Install Claude Code on Windows 11 with Git for Windows (default
core.autocrlf=true) - Install the
ralph-loopplugin:claude plugin install ralph-loop@claude-plugins-official - Run
/ralph-loop Build something --max-iterations 5 --completion-promise DONE - Observe:
Error: Bash command failed for pattern "!..." - Try to exit the session
- Observe:
Stop hook error: /bin/bash: .../stop-hook.sh: No such file or directory
The same issue affects any plugin with .sh files in hooks or command templates, including:
- ralph-loop (official) -
stop-hook.sh,setup-ralph-loop.sh - learning-output-style (official) -
session-start.sh - claude-scientific-writer -
review_poster.sh - document-skills (anthropic-agent-skills) -
init-artifact.sh,bundle-artifact.sh
Confirmed by checking file contents with Node.js:
node -e "const b=require('fs').readFileSync('path/to/stop-hook.sh'); console.log('has CRLF:', b.includes(Buffer.from([0x0d,0x0a])))"
// Output: has CRLF: true
Claude Model
claude-opus-4-6
Is this a regression?
Unknown - may have always been broken on Windows
Claude Code Version
2.1.45 (Claude Code)
Platform
Anthropic Console (API)
Operating System
Windows 11 Pro
Terminal/Shell
Git Bash / PowerShell
Additional Information
Suggested fixes (in order of preference):
- Add
.gitattributesto plugin repos with*.sh text eol=lfto force LF on all platforms - Set
core.autocrlf=falsewhen cloning plugin repos in the installer - Convert
.shfiles to LF after download in the plugin installer post-install step - Use Node.js instead of bash for hooks/scripts (Node.js handles Windows paths natively and is guaranteed available since Claude Code itself runs on Node.js)
Workaround: Convert files manually after install:
node -e "const fs=require('fs'); const f='path/to/script.sh'; fs.writeFileSync(f, fs.readFileSync(f,'utf8').replace(/\r\n/g,'\n'))"
Or rewrite hooks in Node.js and update hooks.json to use node instead of .sh scripts.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗