[BUG] Windows / Desktop Code tab: Bash `cd` into an additional working directory silently re-targets the session's primary working directory (Workflow scripts land under another project's slug)

Status Open
Reported on v2.1.284
Maintainer reply None cached
Activity 2 comments · opened Sep 30, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

A main-thread Bash command such as cd "C:\Users\<user>\Documents\<other-dir>" && ls (no prompt, per the permissions docs: "A cd into a path inside your working directory or an additional directory is also read-only") leaves the shell in <other-dir>. Immediately after that command, still within the same turn, the harness treats <other-dir> as the session's primary working directory:

  1. Before its next step the model receives:

```
<system-reminder>
# Environment update

  • Primary working directory: C:\Users\<user>\Documents\<other-dir> (was C:\Users\<user>\Documents\<project>)

</system-reminder>
``
In the transcript this is
type:"attachment", attachment.type:"environment", changes[{field:"workingDirectory", from:…}]. The cwd field of subsequent records also changes. In one observed case the cd` ran at 13:14:26, the reminder was stored at 13:14:30 and the model's next message came at 13:14:34.

  1. Workflow tool scripts are then saved under the other directory's project slug, ~/.claude/projects/C--Users-<user>-Documents-<other-dir>/<session>/workflows/scripts/*.js, not under <project>'s slug. On this machine (counted 2026-09-30 18:47 CEST) there are 21 such scripts in 9 foreign slug folders, against 35 in the correct one. The oldest is from 2026-08-31. Those foreign folders contain only scripts, with no transcripts or memory. Whether resumeFromRunId still finds these runs was not tested.
  2. The documented way back is ccd_directory__change_directory, which has two problems:
  • It apparently needs approval. The tool description shown to the model says "the user sees and approves that exact folder (in bypass permissions mode it is granted without asking)". In auto mode, 10.6 s, 12.9 s and 15.3 s passed between call and result in the 3 observed calls. That this was the approval wait is inferred from the delay, not measured.
  • It applies only at the end of the turn. The tool result says "The session's working directory will move to this folder when the current turn ends. Until then, use this exact absolute path…". Until then the only visible effect was that <project> was added to additionalWorkingDirectories (in 2 of the 3 observed calls; in the third it was already listed).
  1. Consequence without a human present: the turn keeps running with the foreign primary directory. In one observed session, a Workflow run started about 2.5 minutes after the change_directory call and its script went to the foreign slug. The primary directory came back 6 minutes after the call, 7 s after a cd to a path outside the allowed directories; whether the "Shell cwd was reset to …" that such a cd triggers, or the end of the turn, brought it back was not determined. In a second session (2026-09-24) the pattern was the same: change_directory call, turn ended 39 s later, the primary-directory change was recorded only with the next user prompt about 20 minutes later.

Subagent transcripts show no such change. Since 2026-09-15 they contain 2,308 Bash commands starting with cd (386 transcript files) with 0 working-directory changes and 0 "Shell cwd was reset" messages. In 4 cases (Workflow subagents) a standalone pwd afterwards returned the project directory. The mechanism behind the difference was not verified.

Where it appears to come from (read from the minified 2.1.284 bundle, so function identities are inferred from proximity): after each Bash/PowerShell command the harness resets the shell cwd to originalCwd only when the current cwd is outside the allowed directories, unless CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR is truthy, in which case it resets after every command. The environment snapshot that produces "Primary working directory: … (was …)" takes its cwd from the shell's current cwd.

What Should Happen?

These are questions, not requests:

  • Is it intended that a Bash cd into an additional working directory changes the session's primary working directory, including the project slug that Workflow uses for its scripts, when switching back needs user approval and applies only at end of turn?
  • Should CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR=1 be the default for the Desktop Code tab, as #35058 asked for in March?

Error Messages/Logs

Steps to Reproduce

  1. In the Desktop Code tab, open a session on C:\Users\<user>\Documents\<project> with C:\Users\<user>\Documents as an additional working directory. Permission mode auto. CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR not set.
  2. Ask Claude to run cd "C:/Users/<user>/Documents/<other-dir>" && pwd via Bash (<other-dir> is any folder under Documents other than <project>).
  3. Still in the same turn, an "Environment update — Primary working directory … (was …)" reminder arrives before the model's next step, and the transcript cwd field changes to <other-dir>. Expected: a standalone pwd in a later Bash call also returns <other-dir>.
  4. Start any Workflow. Its script is written under the <other-dir> slug in ~/.claude/projects/.

Claude Model

Not sure / Multiple models

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.284

Platform

Other

Operating System

Windows

Terminal/Shell

Other

Additional Information

  • Related, locked: #35058 "[BUG] Bash tool cd within project root persists across calls by default — breaks statusline, enables silent directory drift" (Windows 11, 2.1.76, opened 2026-03-16). It was closed as a duplicate of #31471 on 2026-03-20 and locked on 2026-03-27; #31471 is closed not_planned and locked. That issue predates the Environment update reminder and the Workflow slug effect.
  • Related, different: #81291 (${CLAUDE_PROJECT_DIR} resolves against a drifted cwd after a mid-session cd; closed not_planned) and #97902 (parallel Bash calls share the shell's working directory; open).
  • Not this report: #42837 and #42844 describe the opposite behavior (cd no longer persisting, macOS, April 2026); both closed.

Claude Code Version / Platform / OS / Shell

  • Claude Code 2.1.284, running as the Code tab of Claude Desktop (transcript entrypoint: claude-desktop). The "Environment update" reminder described below was seen on every version from 2.1.260 to 2.1.284 present in local transcripts; the underlying cd persistence is present from 2.1.209 (oldest local transcript) on.
  • Claude Desktop 2.16120.0.0 (Windows Store/MSIX package Claude_2.16120.0.0, package folder created 2026-09-29). The Desktop version at earlier dates is not known. The last local Desktop log (2026-08-22) shows Desktop 1.34493.1 with Code 2.1.234.
  • Windows 10 Pro 10.0.19045. Bash tool = Git Bash.
  • Session config: primary working directory C:\Users\<user>\Documents\<project>, additional working directories C:\Users\<user>\Documents and C:\Users\<user>\.claude. Permission mode: auto.

Is this a regression? / Onset

Unclear. The following is what the local data show:

  • The cd persistence (transcript cwd changing after cd into an additional directory) is present from the oldest local transcript (2026-07-14, 2.1.209). Nothing older is on disk.
  • The "Environment update — Primary working directory" attachment appears in transcripts from 2.1.260 on (first environment record 2026-09-04, first workingDirectory change 2026-09-05). Before that, no context attachments of that family (environment, instructions, session_context, …) are stored at all. So the data cannot tell whether the model started receiving the reminder in 2.1.260, or whether it was only first persisted then.
  • The Workflow-slug effect predates 2.1.260: first seen 2026-08-31, in a session that ran 2.1.247/2.1.255/2.1.258.
  • The user has shared the same additional directories (Documents, .claude) with sessions for a long time and noticed problems only around mid-September. The transcripts show no change in any of the channels above around 2026-09-15. Whatever changed then (for example change_directory approval behavior or the Desktop version) was not measured.

Frequency (local transcripts, main threads only)

  • Measured 2026-09-15 to 2026-09-30 18:05 CEST: 133 primary-directory switches in 28 sessions (29 transcript files) out of 93 main-session transcripts. In the same period the main thread ran 454 Bash commands starting with cd; 133 of them caused a switch (the rest went to the directory the shell was already in, or outside the allowed directories). The shapes of the switching commands were cd X && … 90×, cd X; … 26× and other or not attributable 17×. Of 98 moves away from the project directory, 40 never returned within the same session.
  • Measured 2026-09-05 to 2026-09-30: 408 "Environment update" working-directory changes in total.
  • Measured 2026-07-14 to 2026-09-04 (2.1.209–2.1.258): 332 main-thread cd commands into Documents/… or .claude/… changed the transcript cwd field with no Environment update reminder stored.

Workaround (verified once)

Add "CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR": "1" to env in ~/.claude/settings.json. This took effect in the already running Desktop session, without a restart. Settings were saved at 18:21:38 CEST. At 18:21:51, cd "…/Documents/<other-dir>" && pwd printed <other-dir>, and at 18:21:55 a standalone pwd printed the project directory. No environment / workingDirectory record followed in any main transcript. Observation time after the change is short (local transcript data end at 18:37), and this is one measurement in one session.

View original on GitHub ↗

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