Skip to content

fix: invoke .sh hooks via bash prefix (fixes #993)#1115

Merged
dicksontsai merged 1 commit intomainfrom
dickson/bash-prefix-hooks
Mar 29, 2026
Merged

fix: invoke .sh hooks via bash prefix (fixes #993)#1115
dicksontsai merged 1 commit intomainfrom
dickson/bash-prefix-hooks

Conversation

@dicksontsai
Copy link
Copy Markdown
Collaborator

@dicksontsai dicksontsai commented Mar 28, 2026

Problem

Hook scripts in ralph-loop, explanatory-output-style, and learning-output-style fail with Permission denied when the .sh file lacks +x (#993).

Fix

Two changes per plugin:

  1. hooks.json: prefix with bash so the script is read as data, not exec'd:

    - "command": "${CLAUDE_PLUGIN_ROOT}/hooks/stop-hook.sh"
    + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/stop-hook.sh\""

    Mode bits are now irrelevant.

  2. plugin.json: add "version": "1.0.0" to invalidate the unknown/ cache — calculatePluginVersion reads the manifest from the freshly-synced marketplace tree, so the new version forces a new cache path and re-extraction.

Why bash, not sh?

All 3 scripts declare #!/bin/bash and use bashisms ([[ ]], =~ regex) that POSIX sh (dash/ash) can't run. Using sh would break them on Debian/Alpine where /bin/sh ≠ bash.

…tion

Fixes #993 (Permission denied on hook scripts) without relying on
client-side +x preservation.

The hook executor spawns commands via /bin/sh -c, which requires +x
to execute a script directly. Prefixing with bash reads the script
as data — mode bits are irrelevant. This works on all Claude Code
versions, whereas the client-side chmod fix (claude-cli #24666) only
shipped in v2.1.86.

All 3 scripts declare #!/bin/bash and use bashisms ([[ ]], =~), so
bash (not sh) is the correct interpreter.

The version field forces a fresh cache path (1.0.0/ instead of
unknown/), ensuring the new hooks.json reaches users with stale
caches.
@dicksontsai dicksontsai merged commit 183a6ca into main Mar 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants