Hook Paths Must Be Absolute
What Happened

We templated the PeonNotify installer with $HOME/.claude/hooks/peon-dispatch.sh as the hook path in settings.local.json. Every hook silently failed : no error message, no log entry, just nothing. Claude Code treats the hook as if it does not exist. Significant debugging time spent before discovering the cause.
Root Cause
Claude Code does NOT expand $HOME, ~, or any shell variable in hook command strings inside settings.local.json. The string is passed verbatim to the OS as the command path, and the OS finds no file at the literal path $HOME/.claude/hooks/peon-dispatch.sh.
This is a silent failure by design: Claude Code does not report hook execution errors to the user, so there is no feedback when a hook path resolves to nothing. The hook appears registered in settings.local.json, the session runs normally, and nothing in the UI indicates that the hook ever fired : or didn’t.
How to Avoid
The installer must resolve $HOME to the absolute path at install time : not at runtime:
# In install.sh:
sed "s|\$HOME|$HOME|g" settings.local.json > ~/.claude/settings.local.json
Never use $HOME, ~, or any shell variable in hook command paths. The final written value must be a fully qualified absolute path like /Users/pluto/.claude/hooks/peon-dispatch.sh.
Related
- projects/peon-notify/_index : parent project
- bash-set-e-arithmetic-trap : companion HOOKS pitfall in the same project
- peon-notify