Plugin hook scripts in cache lose execute permission on extraction (worktree / unknown hash path)
Description
Plugin hook shell scripts extracted into the plugin cache directory lose their execute permission (+x), causing Permission denied errors on every session stop. This appears to specifically affect git worktrees, where the cache path falls back to an unknown/ directory instead of a project-hash-based directory.
Steps to Reproduce
- Install a plugin with a Stop hook (e.g.,
ralph-loopfromclaude-plugins-official) - Open Claude Code from a git worktree (not the main working tree)
- Start a session, then let it stop normally
Expected Behavior
Hook runs successfully.
Actual Behavior
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 cache at ~/.claude/plugins/cache/ creates per-project copies of plugin files, keyed by a hash of the project path:
cache/claude-plugins-official/ralph-loop/8908a582f80d/hooks/stop-hook.sh (-rwxr-xr-x)
cache/claude-plugins-official/ralph-loop/61c0597779bd/hooks/stop-hook.sh (-rwxr-xr-x)
cache/claude-plugins-official/ralph-loop/unknown/hooks/stop-hook.sh (-rw-r--r--) ← broken
For git worktrees, the hash computation apparently fails and falls back to unknown/. The file extracted into unknown/ is missing the execute bit. Running chmod +x fixes it temporarily, but the next session re-extracts the file and overwrites it without +x again.
The hash-based directories (8908a582f80d, etc.) have correct permissions — only unknown/ is affected.
Environment
- macOS (Darwin 25.2.0, arm64)
- Claude Code CLI
- Git worktrees at non-standard paths (e.g.,
~/project-wt2/alongside main~/project/)
Suggested Fix
Either:
- After extracting plugin files into the cache,
chmod +xany.shfiles inhooks/ - Have the hook runner invoke shell scripts via
bash <script>instead of executing them directly, which doesn't require+x - Fix the hash computation to handle worktree paths (resolve to the main repo's
.gitdir)
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗