Hooks are silently absent when the project root isn't the repo root

Status Fixed / completed
Maintainer reply None cached
Activity 2 comments · opened Aug 30, 2026 · closed Aug 30, 2026

.claude/settings.json loads from the session's project root, not the working directory. Start a session one directory above a repo and repo/.claude/settings.json is never loaded — every PreToolUse, PostToolUse and Stop hook silently does not exist.

Nothing signals it. cwd is the repo, the settings file is visibly there, the hooks just never fire. We only found it by comparing transcript_path values between two sessions on the same repo, one started inside it and one above it.

The cost in our case was a full day: a single write that a hook should have blocked went through, that was read as "this client doesn't run project hooks", and three PRs of architecture were built to work around a limitation that did not exist.

Suggested fixes, best first:

  1. Warn at session start when a .claude/settings.json exists below the project root and is not loaded — an unambiguous misconfiguration signal.
  2. Expose the resolved hook configuration, so "is this session governed?" is answerable without probing.
  3. Document the project-root-vs-cwd distinction in the hooks reference — "$CLAUDE_PROJECT_DIR" inside hook commands reads as cwd-relative when it isn't.

Our workaround is a SessionStart hook appending to an audit log, so a session missing from that log is ungoverned. It only works once hooks load, so it cannot catch the case it was written for.

---

Edited: this issue originally also asked for two things that already exist — PostToolUse returning systemMessage/additionalContext as a postcondition check on an edit, and non-zero exit codes being surfaced as transcript errors. Both are documented. The "crashing hook reads as success" claim was true of my own test harness, which mapped any non-2 exit to "allowed"; I generalised my bug into a product defect without reading the reference.

View original on GitHub ↗

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