[Bug] Project context lost when Bash tool changes into nested git repository
Bug Description
What happens
When the Bash tool changes the working directory into a subdirectory that is its own git repository, the session silently degrades. The status line hook disappears, the file picker stops working, all project skills and commands vanish, and project-level hook matchers drop to zero. The session stays alive but becomes effectively unconfigured. Parallel sessions are unaffected.
How to reproduce
- Create a project with
.claude/settings.jsonthat has a status line hook and a file suggestion command using relative paths:
``json``
{
"statusLine": { "type": "command", "command": "node .claude/hooks/my-hook.js" },
"fileSuggestion": { "type": "command", "command": "scripts/file-picker.sh" }
}
- Put a separate git repo inside the project (not a submodule — just an independent repo sitting in a subdirectory, like a monorepo with nested repos).
- Start a Claude Code session from the parent project root. Everything works fine.
- In a Bash tool call,
cdinto the nested git repo subdirectory. - From this point on:
- The status line hook fails with exit code 1 (file not found at the relative path)
- The file picker command fails the same way
- On the next user prompt, skills reload with
project=[]— all project skills gone - Project hook matchers drop from N to 0
- There is no way to recover without restarting the session
Why it happens
The Bash tool persists its working directory between calls. When the cwd moves into a nested git repo, git rev-parse --show-toplevel returns the nested repo's root instead of the parent project's root. Claude Code then re-evaluates the project context from this new git root, which has no .claude/ folder, so everything project-level disappears.
The hook commands are executed relative to the current working directory, not the project root where .claude/settings.json lives. So relative paths like node .claude/hooks/my-hook.js break because that file doesn't exist in the nested repo.
What I'd expect instead
Hook commands, file suggestion commands, and project skill/settings resolution should always be anchored to the project root (the directory containing the .claude/ folder that was detected at session start), regardless of where the Bash tool's working directory has wandered. The project root is a session-level concept — it shouldn't change just because a shell command ran cd.
Debug log evidence
From claude --debug output of an affected session:
# Session start — everything healthy
Loading skills from: ... project=[/path/to/project/.claude/skills]
Loaded 41 unique skills (... project: 27 ...)
StatusLine [node .claude/hooks/my-hook.js] completed with status 0
# After Bash cd'd into nested repo — status line fails
StatusLine [node .claude/hooks/my-hook.js] completed with status 1
# Next user prompt — project context lost
Loading skills from: ... project=[]
Loaded 0 unique skills (... project: 0 ...)
Found 0 hook matchers in settings
bug
Environment Info
- Platform: darwin
- Terminal: ghostty
- Version: 2.1.71
- Feedback ID: 93e9aadd-b18b-4666-aca1-43d94b89f2b1
Errors
[]This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗