Plugin cache strips execute permission from hook scripts

Resolved 💬 1 comment Opened Mar 25, 2026 by greogory Closed Mar 27, 2026

Bug

The plugin cache mechanism strips the execute bit from hook handler scripts when downloading/caching plugins. This causes SessionStart:startup hook error on every session start for affected plugins.

Affected Plugins

  • explanatory-output-stylehooks-handlers/session-start.sh
  • learning-output-stylehooks-handlers/session-start.sh

Details

Both files are committed upstream with mode 100755 (executable):

plugins/explanatory-output-style/hooks-handlers/session-start.sh mode=100755
plugins/learning-output-style/hooks-handlers/session-start.sh mode=100755

But after plugin cache download, the local copies have 644 (not executable):

-rw-r--r-- 1 bosco bosco 1468 Mar 25 08:20 session-start.sh
-rw-r--r-- 1 bosco bosco 3564 Mar 25 08:20 session-start.sh

Since the hooks.json command references the script directly (${CLAUDE_PLUGIN_ROOT}/hooks-handlers/session-start.sh), Claude Code fails to execute it.

Why superpowers is unaffected

The superpowers plugin works around this by using a polyglot .cmd wrapper (run-hook.cmd) which retains its execute bit. The wrapper explicitly calls bash on the target script, bypassing the permission issue.

Workaround

chmod +x ~/.claude/plugins/cache/claude-plugins-official/explanatory-output-style/unknown/hooks-handlers/session-start.sh
chmod +x ~/.claude/plugins/cache/claude-plugins-official/learning-output-style/unknown/hooks-handlers/session-start.sh

This workaround is fragile — the next plugin cache refresh will likely restore the broken permissions.

Suggested Fix

Either:

  1. Preserve git file modes (100755) when downloading plugin files to cache
  2. Or auto-detect and chmod +x any file referenced by a command field in hooks.json

Environment

  • Claude Code 2.1.83
  • Linux (CachyOS / Arch-based)
  • bash 5.2

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗