[BUG] Bash tool cd within project root persists across calls by default — breaks statusline, enables silent directory drift

Resolved 💬 3 comments Opened Mar 16, 2026 by dkodr Closed Mar 20, 2026

[BUG] Bash tool cd within project root persists across calls by default — breaks statusline, enables silent directory drift

Preflight Checklist

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

What's Wrong?

When the Bash tool executes cd to a subdirectory within the project root, the new working directory persists across subsequent Bash tool calls. Only cd outside the project root triggers a CWD reset.

This causes two concrete problems:

  1. Statusline breaks: A statusLine command that relies on pwd (e.g., showing git branch/status) loses context after a subagent or the model itself runs cd to a subdirectory. The statusline then reports incorrect git information or fails entirely.
  1. Silent directory drift: When subagents perform cd to explore other directories (especially via /add-dir), the main session's CWD silently changes. The user has no indication that subsequent commands will run in a different directory. In one real session, a subagent's cd shifted CWD to an entirely different repository (added via /add-dir) for 17 minutes and 114 log entries before it was reset.

What Should Happen?

CWD should reset to the project root after every Bash tool call, regardless of whether cd targeted a path inside or outside the project. This is what CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR=1 does — but it's not the default, and it's completely undocumented.

Steps to Reproduce

Test 1 — cd within project (default behavior, no env var)

  1. Start Claude Code in a project directory (e.g., /home/user/my-project/)
  2. Run Bash: cd src && pwd → outputs /home/user/my-project/src
  3. Run Bash: pwd → outputs /home/user/my-project/src (persisted — wrong)

Test 2 — cd outside project (default behavior, no env var)

  1. Run Bash: cd /tmp && pwd → outputs /tmp
  2. Run Bash: pwd → outputs /home/user/my-project/ (reset — correct)

Test 3 — with CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR=1

  1. Set CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR=1 in settings.json env
  2. Restart Claude Code
  3. Run Bash: cd src && pwd → outputs /home/user/my-project/src
  4. Run Bash: pwd → outputs /home/user/my-project/ (reset — correct)

Real-world impact (session evidence)

In a real session using a git worktree, the following CWD transitions were observed in the JSONL log:

| Time | CWD changed to | Trigger |
|------|----------------|---------|
| 13:19 | repo-B (different repo, added via /add-dir) | Subagent cd |
| 13:19 | Back to project root (repo-A worktree) | Reset |
| 13:19 | repo-B again | Another subagent cd |
| 13:19 | Back to project root | Reset |
| 13:35 | repo-B | Subagent cd — persisted for 17 minutes |
| 13:52 | Back to project root | Reset |

During the 13:35–13:52 window, 114 JSONL log entries had "cwd" pointing to repo-B instead of the actual project root. Any Bash commands during that period would have executed in the wrong repository. The user had no visual indication of this — the CWD shift was completely silent.

The inconsistency

| Scenario | Default behavior | With env var =1 |
|----------|-----------------|-------------------|
| cd outside project | Reset + visible message | Reset (silent) |
| cd within project | No reset (persists) | Reset (silent) |
| cd to /add-dir path | No reset (persists) | ? (not tested) |

The env var also suppresses the "Shell cwd was reset" message, making the reset silent in all cases.

Questions for the team

  1. Why isn't CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR=1 the default? The variable has existed since v1.0.18, so the team clearly identified the problem. The current default breaks the statusline and enables silent directory drift.
  1. Why is this variable undocumented? Issue #9359 requested documentation and was closed as "not planned". The variable doesn't appear in the settings docs or any official reference.
  1. Should /add-dir directories be treated as "within project"? The current behavior allows cd to an /add-dir path to persist, which is arguably even more dangerous than within-project persistence since it's a completely different repository.

Proposed fix

Change the default to CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR=1 (always reset CWD to project root). Users who need the old behavior can set =0. Also document the variable.

Error Messages/Logs

No error messages — the issue is silent by nature, which makes it worse.

Claude Model

Opus 4.6

Is this a regression?

No — this has been the behavior since at least v1.0.18 (when the env var was introduced as a workaround)

Claude Code Version

2.1.76

Platform

Anthropic API (Max subscription)

Operating System

Windows 11 Pro (10.0.26200) with Git Bash

Terminal/Shell

Windows Terminal + Git Bash

Additional Information

Related issues:

  • #9359 — Documentation request for CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR (closed "not planned")
  • #11067 — Bash Tool Not Respecting Working Directory
  • #14300 — Shell initialization breaks workspace boundary
  • #16361 — Working directory does not persist between Bash commands on Windows
  • #7442 — Claude will frequently cd and then forget its working directory

View original on GitHub ↗

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