Project .claude/settings.json hooks not loaded when session starts from subdirectory

Resolved 💬 3 comments Opened Mar 13, 2026 by wmatson-skyslope Closed Mar 13, 2026

Environment

  • Claude Code Version: Latest (March 2026)
  • Platform: macOS Darwin 25.3.0
  • Node: v20.19.5

Description

Hooks defined in a project's .claude/settings.json at the git repo root do not fire when the Claude Code session is started from a subdirectory (e.g., apps/api-core in a monorepo).

This is a re-report of #10367, which was auto-closed. The issue still reproduces.

Reproduction

Repo structure (monorepo):

repo-root/
  .claude/
    settings.json     # PostToolUse hook defined here
    hooks/
      format-file.sh  # Runs prettier on edited files
  apps/
    api-core/         # <-- session started from here

.claude/settings.json:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": ".claude/hooks/format-file.sh",
            "timeout": 30
          }
        ]
      }
    ]
  }
}

Steps:

  1. cd repo-root/apps/api-core
  2. Start Claude Code
  3. Ask Claude to edit a .js file with intentionally bad formatting
  4. Observe that the PostToolUse hook does not fire — formatting is not corrected
  5. Run the hook script manually with the same JSON input — it works perfectly

From the repo root, the hook fires (sometimes with errors due to a separate stdout issue, but it does engage).

Expected behavior

.claude/settings.json at the git root should be discovered and loaded regardless of which subdirectory the session was started from. git rev-parse --show-toplevel correctly returns the repo root, so the information is available.

Workaround

Added instructions in the root CLAUDE.md telling Claude to run npx prettier --write manually when the hook isn't active. This works but is fragile and not a real substitute for the hook.

Impact

In monorepos, developers commonly start sessions from app subdirectories. Project-level hooks (formatting, linting, validation) are team-shared via .claude/settings.json checked into the repo. These hooks silently fail to load for anyone not starting from the exact repo root, with no warning.

Related

  • #10367 (auto-closed, same root cause)
  • #8810 (subdirectory hook issues)

View original on GitHub ↗

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