Plugin marketplace strips execute permissions from .sh hook files
Bug
Shell script files (.sh) downloaded from the official plugin marketplace (claude-plugins-official) are missing the execute permission bit. This causes hooks to fail with "Permission denied" every time they run.
Steps to Reproduce
- Install a plugin that includes shell script hooks (e.g.,
ralph-loop) - Trigger the hook (e.g., the
stop-hook.shfires on session stop) - Observe the error:
Stop hook error: Failed with non-blocking status code: /bin/sh:
/Users/<user>/.claude/plugins/marketplaces/claude-plugins-official/plugins/ralph-loop/hooks/stop-hook.sh: Permission denied
Root Cause
The plugin sync mechanism downloads files without preserving the execute bit. All .sh files end up with -rw-r--r-- permissions instead of -rwxr-xr-x.
This affects every .sh file in the marketplace — not just ralph-loop. Verified by checking all .sh files in the directory:
find ~/.claude/plugins/marketplaces/claude-plugins-official -name "*.sh" -exec ls -la {} \;
All 16 .sh files had -rw-r--r-- permissions.
Workaround
Manually fix permissions after install/update:
find ~/.claude/plugins/marketplaces/claude-plugins-official -name "*.sh" -exec chmod +x {} \;
This workaround resets on every plugin sync/update.
Expected Behavior
Shell scripts in plugins should be executable after install/sync. The marketplace sync should either:
- Preserve the execute bit from the source repository
- Automatically
chmod +xany.shfiles after download - Respect a
fileModefield inplugin.jsonmetadata
Environment
- macOS (Darwin 25.3.0)
- Claude Code CLI (latest)
- Plugin:
ralph-loop@claude-plugins-official(and all other plugins with.shfiles)
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗