[BUG] .claude/settings.json and settings.local.json resolve against literal cwd, not git root — subdirectory launches silently drop all project settings

Open 💬 3 comments Opened Jul 3, 2026 by ElijahLynn

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet as an open issue
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Code

What's Wrong?

.claude/settings.json and .claude/settings.local.json are resolved against the literal cwd, not the git root. When Claude Code is launched from a subdirectory of a repo, all project-scoped settings — hooks, permissions/allow-rules, enabledPlugins, autoMemoryDirectory, etc. — silently disappear, with no error. CLAUDE.md and skills correctly walk up to the repo root in the same session, so this is a settings-specific resolution bug, not a general cwd-discovery issue.

This looks like the same underlying bug as #36793 ("Project settings hooks not loaded when working directory is a subdirectory of the repo") and its duplicate #44278 ("Project-scoped settings don't resolve from subdirectories, making project scope identical to local scope"). Both were closed — #36793 auto-closed 2026-05-30 as inactive (not fixed, not rejected on the merits), #44278 closed as a duplicate of #36793. I'm filing fresh per the bot's own instruction on #36793 ("open a new issue if this is still relevant"), since it still reproduces on a version far newer than the close date.

What's new here vs. #36793 / #44278

  • A debug session ruled out the workspace-trust gate as an alternative explanation via an intervention test — settings from the subdirectory launch stayed unloaded regardless of trust state. So this is not the trust gate; it's pure path resolution happening before or independent of that gate.
  • Confirmed affected by the same root cause: hooks, permissions/allow-rules, enabledPlugins, and autoMemoryDirectory (all silently drop from a subdirectory launch).
  • A local .claude/settings.local.json with an absolute path value does not fix the underlying issue either — the settings file itself isn't found from the subdirectory in the first place, so its contents never come into play.
  • Below is an actually-executed, copy-pasteable repro with real captured output and --debug-file evidence (see "Steps to Reproduce"), not just a description.

What Should Happen?

.claude/settings.json and .claude/settings.local.json should resolve by walking up from the working directory to the nearest git root (the same resolution CLAUDE.md already uses), so all project-scoped config is available from any subdirectory within the project.

Steps to Reproduce

# 1. Create a minimal repo with a project-level hook that blocks edits
mkdir settings-cwd-repro && cd settings-cwd-repro
git init -q

mkdir .claude subdir
cat > .claude/settings.json <<'EOF'
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          { "type": "command", "command": "echo 'HOOK FIRED' >&2; exit 2" }
        ]
      }
    ]
  }
}
EOF
echo hello > file.txt
echo hello > subdir/file.txt
git add -A && git commit -q -m "init repro"

# 2. From the repo root — the hook fires and blocks the edit (WORKS)
claude --permission-mode acceptEdits --allowedTools "Edit" -p \
  "Edit file.txt to say 'modified'. Report verbatim whether it succeeded or was blocked."

# 3. From the subdirectory — same repo, same committed settings.json (FAILS)
cd subdir
claude --permission-mode acceptEdits --allowedTools "Edit" -p \
  "Edit file.txt to say 'modified'. Report verbatim whether it succeeded or was blocked."

I ran this exact script on v2.1.198. Actual output:

Step 2 (repo root):

The edit was blocked. Verbatim tool error returned: `` PreToolUse:Edit hook error: [echo 'HOOK FIRED' >&2; exit 2]: HOOK FIRED ``

Step 3 (subdirectory):

Edit result (verbatim): The edit tool call succeeded, no hook blocked it. ... no .claude/settings*.json exist in this project directory

That last line is the subagent itself confirming the divergence — from the subdirectory it can't find .claude/settings.json at all, because it's looking in the wrong place.

Direct confirmation via --debug-file on the same two runs — the line the harness logs at startup, listing every settings file it will watch for changes:

From the repo root:

[DEBUG] Watching for changes in setting files /home/elijah/.claude/settings.json, /path/to/settings-cwd-repro/.claude/settings.json, /path/to/settings-cwd-repro/.claude/settings.local.json...

From subdir/:

[DEBUG] Watching for changes in setting files /home/elijah/.claude/settings.json...

From the subdirectory, the repo's own .claude/settings.json and .claude/settings.local.json never even enter the watch list — the resolver looks for subdir/.claude/settings.json (confirmed via the adjacent "Broken symlink or missing file encountered for settings.json at path: .../subdir/.claude/settings.json" debug line), finds nothing, and silently gives up instead of walking up to the git root the way CLAUDE.md resolution does.

Claude Model

N/A (harness-level bug, not model-dependent)

Is this a regression?

Unclear — #36793 reports this as a regression from a state that worked "confirmed working ~March 6, 2026," but I don't have version-pinned before/after evidence myself.

Claude Code Version

2.1.198

Platform

Anthropic API

Operating System

Linux

Terminal/Shell

fish

Additional Information

Workaround: always launch claude from the repo root — e.g. a shell wrapper that cds to ` git rev-parse --show-toplevel first before invoking claude`.

Related/likely-same-family issues: #36793, #44278, #57563, #55973.

View original on GitHub ↗

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