Plugin update loses executable permission on .sh hook files

Status Fixed / completed
Maintainer reply ✓ Yes — ashwin-ant
Activity 4 comments · opened Mar 28, 2026 · closed Apr 18, 2026
💡 Likely answer: A maintainer (ashwin-ant, collaborator) responded on this thread — see the highlighted reply below.

claude plugin update downloads plugin files without preserving the executable bit on .sh files. This causes hook execution to fail with:

Stop hook error: Failed with non-blocking status code: /bin/sh: 1:
/home/user/.claude/plugins/marketplaces/.../hooks/stop-hook.sh: Permission denied

Reproduction

  1. Install a plugin with .sh hook files (e.g. ralph-loop from claude-plugins-official)
  2. chmod +x the hook files manually so hooks work
  3. Run claude plugin update claude-plugins-official@anthropic
  4. Hook files lose +x → hooks fail with "Permission denied"

Expected behavior

claude plugin update should either preserve executable permissions on .sh files during download, or automatically chmod +x all .sh files after update.

Workaround

find ~/.claude/plugins/marketplaces -name "*.sh" -exec chmod +x {} \;

Needs to be re-run after every plugin update.

Environment

  • Platform: Linux
  • Affects all .sh files across all marketplace plugins

View original on GitHub ↗

4 Comments

yurukusa · 6 months ago

A SessionStart hook can auto-fix permissions on every session start:

PLUGIN_DIR="$HOME/.claude/plugins"
if [ -d "$PLUGIN_DIR" ]; then
    find "$PLUGIN_DIR" -name "*.sh" ! -perm -u+x -exec chmod +x {} + 2>/dev/null
    FIXED=$(find "$PLUGIN_DIR" -name "*.sh" -newer /tmp/.cc-permission-fix-marker 2>/dev/null | wc -l | tr -d ' ')
    [ "$FIXED" -gt 0 ] && echo "Fixed permissions on $FIXED hook script(s)" >&2
fi
touch /tmp/.cc-permission-fix-marker
HOOKS_DIR="$HOME/.claude/hooks"
if [ -d "$HOOKS_DIR" ]; then
    find "$HOOKS_DIR" -name "*.sh" ! -perm -u+x -exec chmod +x {} + 2>/dev/null
fi
exit 0
{
  "hooks": {
    "SessionStart": [{
      "hooks": [{ "type": "command", "command": "bash -c 'find ~/.claude/plugins -name *.sh ! -perm -u+x -exec chmod +x {} + 2>/dev/null; find ~/.claude/hooks -name *.sh ! -perm -u+x -exec chmod +x {} + 2>/dev/null'" }]
    }]
  }
}

The one-liner version is simpler — just chmod +x all .sh files under plugins and hooks directories on every session start. Since this runs before any hooks fire, it fixes the permission-denied error before it can occur.
For a more targeted fix after plugin update specifically, you can also add an alias or wrapper:

alias claude-plugin-update='claude plugin update "$@" && find ~/.claude/plugins -name "*.sh" -exec chmod +x {} +'
marlvinvu · 6 months ago

My Claude says your issue has the same execute permission bug as #39931, #39954, #40009, #40050, #40086, #40187. This has been reported 7 times now.

ashwin-ant collaborator · 6 months ago

This was fixed in v2.1.86 — Plugin updates now preserve the executable permission on .sh hook files. If you're still seeing this in the latest version, please comment with your version and repro and we'll reopen.

github-actions[bot] · 5 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.