Plugin hook scripts fail when synced without execute permissions

Resolved 💬 3 comments Opened Jan 25, 2026 by rcfa Closed Jan 29, 2026

Plugin hook scripts fail when synced without execute permissions

Summary

Claude Code plugin hooks that use shell scripts fail with "Permission denied" when the plugin cache is synced between machines using cloud sync services (pCloud, Dropbox, iCloud Drive, etc.) that don't preserve Unix file permissions.

Environment

  • Claude Code version: (current)
  • OS: macOS 15.3 (also affects Linux users syncing configs)
  • Shell: bash/zsh

Steps to Reproduce

  1. Install Claude Code on Machine A
  2. Enable plugins that include shell-based hooks (e.g., learning-output-style)
  3. Sync ~/.claude/plugins/ directory to Machine B via a cloud sync service
  4. Start Claude Code on Machine B
  5. Observe "Permission denied" errors for plugin hook scripts

Error Output

/bin/sh: /Users/rcfa/.claude/plugins/cache/claude-plugins-official/learning-output-style/e30768372b41/hooks-handlers/session-start.sh: Permission denied

Root Cause

Plugin hook scripts are executed directly (e.g., /bin/sh script.sh or ./script.sh) which requires the execute bit to be set. Cloud sync services typically sync file contents but not Unix permissions, resulting in scripts with -rw-r--r-- permissions that cannot be executed.

Suggested Fix

Modify the plugin hook execution logic to use one of these approaches instead of direct execution:

Option 1: Source the script

bash -c "source /path/to/hook.sh"

Option 2: Pass script as argument to interpreter

/bin/bash /path/to/hook.sh

Option 3: Read and execute

/bin/bash -c "$(cat /path/to/hook.sh)"

This matches the pattern already used in user-configured hooks in ~/.claude/settings.json:

{
  "command": "bash -c 'source ~/.claude/merge-history.sh'"
}

Workaround

Users can work around this by periodically running:

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

Or setting up a LaunchAgent/systemd service to watch the directory and fix permissions automatically.

Impact

  • Affects users who sync their Claude configuration between multiple machines
  • Causes plugin hooks to silently fail or produce error output
  • Common with developers who work across multiple computers

Related

This applies to all plugin shell scripts, not just hooks - any .sh file in the plugin structure that gets executed directly will fail.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗