Skip to content

fix(hooks): use $CLAUDE_PROJECT_DIR for Stop-hook commands (AL-34)#20

Merged
Roo4L merged 1 commit into
masterfrom
fix/al-34-stop-hook-cwd-portability
May 9, 2026
Merged

fix(hooks): use $CLAUDE_PROJECT_DIR for Stop-hook commands (AL-34)#20
Roo4L merged 1 commit into
masterfrom
fix/al-34-stop-hook-cwd-portability

Conversation

@Roo4L
Copy link
Copy Markdown
Owner

@Roo4L Roo4L commented May 9, 2026

Summary

Both Stop-hook commands in .claude/settings.json use CWD-relative paths (.claude/hooks/<name>.sh). When the hook runtime invokes them via /bin/sh -c, the relative path resolves against the session's CWD — so launching Claude Code from anywhere other than the project root breaks both reminder hooks with "not found".

Symptom (observed today)

Stop hook error: Failed with non-blocking status code:
  /bin/sh: 1: .claude/hooks/review-reminder.sh: not found
Stop hook error: Failed with non-blocking status code:
  /bin/sh: 1: .claude/hooks/session-tracker-reminder.sh: not found

The scripts themselves are present in the repository on every branch. Pure path-resolution failure.

Fix

Prepend $CLAUDE_PROJECT_DIR to each command, with the whole path enclosed in escaped double-quotes inside the JSON string so project paths containing spaces don't break the shell parse. Standard Claude Code hook-portability pattern.

Audit

Searched the rest of the .claude/ tree for similar relative-path patterns. The only command fields in any settings.json file are these two hooks. Skill SKILL.md and agent definition files use Claude Code's own loader (project-anchored), not /bin/sh from a CWD, so they're not affected.

Test plan

  • gate-1-precommit (only .claude/settings.json changed; pre-commit JSON-schema check should pass)
  • gate-2-docker × {22.04, 24.04, 26.04} (no behavioral change to installer; should pass clean)
  • After merge: launch Claude Code from at least one directory above the project root, trigger a Stop event, verify both reminders fire with their expected text and no shell-not-found errors

Refs: AL-34

Both Stop-hook commands in `.claude/settings.json` referenced the
hook scripts via the relative path `.claude/hooks/<name>.sh`. The
hook runtime invokes those commands via `/bin/sh -c`, which resolves
relative paths against the session's current working directory. When
Claude Code is launched from any directory other than the project
root, the shell reports "not found" for both hooks and the Stop-hook
chain emits a non-blocking warning instead of running the reminders.

Symptom observed in a real session today (2026-05-09):

    Stop hook error: Failed with non-blocking status code:
      /bin/sh: 1: .claude/hooks/review-reminder.sh: not found
    Stop hook error: Failed with non-blocking status code:
      /bin/sh: 1: .claude/hooks/session-tracker-reminder.sh: not found

The hook scripts themselves are present in the repository on every
branch. Pure path-resolution failure.

Fix: prepend `$CLAUDE_PROJECT_DIR` to each command, with the whole
path enclosed in double quotes (escaped within the JSON string) so
project paths containing spaces don't break the shell parse. This is
the documented Claude Code hook-portability pattern.

Audit: searched the rest of the .claude tree for similar relative-path
patterns. The only `command` fields in any settings.json file are these
two hooks. Skill SKILL.md and agent definition files use Claude Code's
own loader (project-anchored), not `/bin/sh` from a CWD, so they are
not affected.

Acceptance: launching Claude Code from at least one directory above the
project root, then triggering a Stop event, shows both hook reminders
firing with their expected text and no shell-not-found errors in the
transcript.

Refs: AL-34.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Roo4L Roo4L force-pushed the fix/al-34-stop-hook-cwd-portability branch from 4da5a5e to 51dfdfd Compare May 9, 2026 08:01
@Roo4L Roo4L merged commit a812a02 into master May 9, 2026
12 checks 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.

1 participant