Stop hooks fail with 'spawn /bin/sh ENOENT' on macOS
Resolved 💬 2 comments Opened Jan 9, 2026 by Morriz Closed Jan 9, 2026
Description
Stop hooks fail to execute with the error spawn /bin/sh ENOENT even though /bin/sh exists and is accessible.
Environment
- Claude Code version: 2.1.1
- OS: macOS Darwin 25.1.0
- Shell:
/bin/shexists at-rwxr-xr-x 1 root wheel 101232 /bin/sh
Steps to Reproduce
- Configure Stop hooks in
~/.claude/settings.json:
{
"hooks": {
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "/path/to/python /path/to/script.py stop"
}
]
}
]
}
}
- Also have a plugin with Stop hooks enabled (e.g.,
ralph-loopplugin)
- Run Claude Code and let it complete a response (trigger Stop event)
Expected Behavior
Stop hooks should execute successfully.
Actual Behavior
Both Stop hooks fail with:
Ran 2 stop hooks
⎿ Stop hook error: Failed with non-blocking status code: Error occurred while executing hook command: spawn /bin/sh ENOENT
⎿ Stop hook error: Failed with non-blocking status code: Error occurred while executing hook command: spawn /bin/sh ENOENT
Analysis
/bin/shexists and is executable- Hook scripts are executable and have correct permissions
- The error occurs for ALL Stop hooks (both user-configured and plugin hooks)
- This suggests the issue is in the hook execution layer, not the individual hooks
- Node.js
child_process.spawn()appears unable to find the shell in the execution environment
Workaround
Currently disabling hooks that use the Stop event.
Additional Context
The hooks work fine for other events (SessionStart, SubagentStop, etc.) based on logs. The issue appears specific to the Stop hook execution context.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗