Shell tool working_directory parameter silently ignored in multi-root workspaces — commands run in first workspace root instead

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

The Shell tool’s working_directory parameter is silently ignored in multi-root workspaces. Commands run in the first workspace root instead of the path passed in, with no error returned. The tool’s output footer even claims the cwd is the path I specified, but a follow-up pwd in a later Shell call reveals the cwd was actually the first workspace root — and files get written to the wrong repo.

Two older forum threads describe the same symptom class:

Neither fix covers the multi-root + explicit working_directory case on Cursor 3.1.17.

Steps to Reproduce

  1. Open a single Cursor window with a multi-root workspace containing two git repos, e.g.:

    • /Users//projects/repo-a (listed first)
    • /Users//projects/repo-b
  2. Ask the agent to create a directory tree inside repo-b, e.g.
    “create subdir-1/{foo,bar}/.gitkeep in repo-b”.

  3. The agent calls the Shell tool with:
    command: “mkdir -p subdir-1/{foo,bar} && touch subdir-1/{foo,bar}/.gitkeep && ls -la subdir-1/”
    working_directory: “/Users//projects/repo-b”

  4. Shell output footer reads:
    Current directory: /Users//projects/repo-b
    and the ls -la subdir-1/ at the end appears to succeed.

  5. In a later Shell call, run pwd and ls /Users/<me>/projects/repo-b/subdir-1.

    • pwd returns /Users//projects/repo-a (the FIRST workspace root).
    • ls on repo-b returns “No such file or directory”.
    • ls /Users/<me>/projects/repo-a/subdir-1 shows the tree — the writes landed in the wrong repo.

Expected Behavior

When working_directory is passed to the Shell tool, the command must execute with that cwd. If the parameter cannot be honored, the tool should return an error and NOT execute — rather than silently running in the first workspace root while still reporting "Current directory: " in the output footer.

The misleading footer is the worst part: it actively tells the agent the command ran where it was asked to, so the agent has no way to detect the mis-routing without an extra verification step.

Operating System

MacOS

Version Information

Cursor version: 3.1.17 (commit fce1e9ab7844f9ea35793da01e634aa7e50bce90, arm64)
OS: macOS 25.4.0 (darwin)
Workspace: multi-root (20 folders added to one window)

For AI issues: which model did you use?

Claude (Sonnet/Opus tier) via built-in Cursor agent mode

Additional Information

Impact: destructive and silent. Writes land in the wrong repo with no indication. For engineers working across multi-root workspaces (common pattern — I had 20 repos open in one window), this is a silent correctness bug with a wide blast radius (misplaced commits, stray files under the wrong .git, accidental secrets-leakage scenarios).

Current workaround I’m using:

  • Ignore working_directory entirely and prefix every command with cd /abs/path && … in a single command string, OR
  • Use absolute paths in every mkdir/touch/cp/etc., OR
  • Open every Shell call with pwd as a sanity probe.

Does this stop you from using Cursor

No - Cursor works, but with this issue

Hi @reiz_fizz
This is a confirmed bug – thanks for the detailed write-up with reproduction steps. You’re right that the working_directory parameter is being silently overridden, and the misleading footer makes it especially frustrating since the agent has no way to detect the mis-routing.

We’ve been investigating this with other users who reported the same issue, and we’ve identified the root cause. A fix is being tracked and worked on by our desktop team.

In the meantime, your workarounds are exactly right – the most reliable approach is to prefix commands with cd /absolute/path && ... or use absolute paths throughout. I know that’s inconvenient, especially with 20 folders in one window.

You may also find this related thread helpful, where several other users are tracking the same issue: Shell tool does not reliably honor working_directory

I’ll follow up here once a fix ships.

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

In a Cursor workspace containing multiple Git repositories, the Shell tool’s working_directory parameter does not reliably re-root the command in the target repository. Commands — especially git — silently keep operating on the first repository listed in the workspace (the “primary” workspace root), even when an absolute path to a sibling repo is passed as working_directory.

This means that when the user asks the agent about a commit / branch / file that only exists in a non-primary repo, the agent gets fatal: bad object <sha>, “branch not found”, etc., and has no obvious feedback that its working_directory was effectively ignored. The agent then spends a lot of tokens hunting for something in a repo that can never contain it. The only reliable workaround is to avoid the working_directory parameter entirely and inline cd /absolute/path && <cmd> instead.

Bonus: the Shell tool’s post-amble cheerfully reports Current directory: /absolute/path/to/sibling-repo even when the spawned process clearly didn’t run there — so the agent has no signal that anything went wrong.

Steps to Reproduce

  1. Open a Cursor workspace whose Workspace Paths list contains at least two separate Git repos — e.g. repo-A listed first, repo-B listed second. (At Datadog this is normal: we routinely have dd-source, web-ui, browser-sdk, etc. all in one workspace.)
  2. Make sure each repo has commits the other does not.
  3. Start a fresh chat. Ask the agent something only repo-B can answer, e.g.:

    In repo-B, what does commit <sha that only exists in repo-B> change?

  4. (Optional, to make this even more egregious) Explicitly warn the agent in the prompt that the workspace root is repo-A and that it must navigate to repo-B first.
  5. Watch the agent call Shell with working_directory: /abs/path/to/repo-B and a git show <sha> / git log … command.
  6. Observe that the output is from repo-A: wrong branch, wrong commits, wrong untracked files, or fatal: bad object. The post-amble still says Current directory: /abs/path/to/repo-B.
  7. Have the agent instead run cd /abs/path/to/repo-B && git show <sha> inline (no working_directory parameter) — and observe it now works.

Expected Behavior

When working_directory is set on a Shell call:

  • The spawned process’s CWD should actually be that directory, so git (and any other CWD-sensitive tool) operates on the repo at that path.
  • If for any reason CWD can’t be set, the tool should fail loudly instead of silently running against the workspace root.
  • The post-amble’s Current directory: line should reflect the actual CWD of the executed command (e.g. pwd after the command), not just echo back the requested working_directory.

Operating System

MacOS

Version Information

Version: 3.5.17 (Universal)
VSCode Version: 1.105.1
Commit: d5b2fc092e16007956c9e5047f76097b9e626ca0
Date: 2026-05-20T02:43:31.559Z
Layout: glass
Build Type: Stable
Release Track: Default
Electron: 39.8.1
Chromium: 142.0.7444.265
Node.js: 22.22.1
V8: 14.2.231.22-electron.0
OS: Darwin arm64 25.5.0

For AI issues: which model did you use?

claude-opus-4-7-thinking-xhigh

Additional Information

Observed evidence from a real session

Workspace (anonymized — real session had 7 sibling repos under one parent directory):

Workspace Paths:
  - /Users/<me>/code/repo-A   ← primary
  - /Users/<me>/code/repo-B
  - /Users/<me>/code/repo-C
  - /Users/<me>/code/repo-D
  - /Users/<me>/code/repo-E
  - /Users/<me>/code/repo-F
  - /Users/<me>/code/repo-G

User asked about commit <sha-in-repo-B> in repo-B and pre-warned the agent that the current working directory was misleading.

  1. Shell call: git status && git branch --show-current && git log --oneline -10
    working_directory: /Users/<me>/code/repo-B
    → Branch reported was the branch checked out in repo-A, not repo-B. Untracked files matched the repo-A git_status block from the system prompt, not repo-B’s.
  2. Shell call: git worktree list with the same working_directory.
    → Returned repo-A’s worktrees.
  3. Reading /Users/<me>/code/repo-B/.git/HEAD directly confirmed the repo was on a different branch than what the earlier git status reported — i.e. those git calls clearly hadn’t run inside repo-B at all.
  4. Shell post-amble said Current directory: /Users/<me>/code/repo-B, but running env later revealed PWD=/Users/<me>/code/repo-A and OLDPWD=/Users/<me>/code/repo-A. So the post-amble’s “Current directory” line is misleading — it appears to echo the requested working_directory, not the actual session CWD.
  5. Once the agent switched to cd /Users/<me>/code/repo-B && git show <sha> inline, the command immediately worked and resolved the commit.

So in this session: every git invocation that relied on working_directory ran against the wrong repo; every inline-cd version worked.

Why this matters

Multi-repo Cursor workspaces are common in monorepo-adjacent setups (frontend repo + backend repo + SDK + tooling, all open at once). When the user asks about anything in a non-primary repo, the agent:

  • Gets fatal: bad object, branch-not-found, or empty results.
  • Has no diagnostic signal that its working_directory was effectively ignored (the tool tells it the CWD is fine).
  • Spirals: tries --all, walks worktrees, fetches, even doubts whether the user remembered the SHA correctly.
  • Burns a large number of tokens before stumbling onto inline cd as a workaround.

Even when the user explicitly pre-warns the agent (as in this session), the agent still gets tricked because it trusts the Shell tool’s reported Current directory: line.

Suggested fixes

  1. Make working_directory actually change the spawned process’s CWD (or fail loudly if it can’t), so child processes — git in particular — see the right repo.
  2. Change the Shell post-amble’s Current directory: line to be derived from a real pwd after the command, not from the requested working_directory.
  3. Optionally: when a workspace contains multiple git repos, document in the Shell tool description that working_directory is per-call only and that inline cd is the safer pattern for chained git commands.

Does this stop you from using Cursor

No - Cursor works, but with this issue

Still reproducing on Cursor 3.11.13 (commit 3f21b08, 2026-07-10), macOS (Darwin 25.5.0) — so this has survived well past the 3.1.x / 3.5.x builds above. Adding a git-worktree variant with two wrinkles that make it worse than the multi-repo case already described.

1. It’s not just separate repos — it hits git worktrees of the same repo, and there it’s destructive.
Setup: one repo with two worktrees on different branches:

/…/repo           (branch: dev)      ← workspace root / persistent shell CWD
/…/repo-feature   (branch: feature)  ← target, passed as working_directory on every call

Because worktrees share one ref store but have separate HEADs, a mis-routed mutation doesn’t just write to the wrong folder — it moves the wrong branch. In our session a git reset --hard origin/feature then git merge origin/main, both issued with working_directory=/…/repo-feature, actually ran in /…/repo and rewrote dev. The dev reflog is the smoking gun (branch names anonymized):

<sha> dev@{1}: reset: moving to origin/feature   ← was meant for the feature worktree
<sha> dev@{0}: merge origin/main: Merge made by the 'ort' strategy

2. The mis-route correlates specifically with mutating / approval-gated calls.
Unlike the “always runs in the first root” reports above, read-only probes (git branch --show-current, git rev-parse --show-toplevel) frequently DID honor working_directory and reported the correct worktree — but the mutating, approval-gated commands (git reset --hard, git merge, git checkout -B) fell back to the persistent shell CWD (workspace root). So an agent can confirm it’s “in” the right worktree with a read-only check, then have the very next destructive command land elsewhere. That makes the misleading Current directory: footer even more dangerous.

Impact: silent, destructive local branch-pointer corruption that crosses subagent/session boundaries — a mutation from one worktree/session clobbered another worktree’s checkout mid-run. Remote refs were spared only because the resulting push was rejected non-fast-forward.

Workaround (consistent with the thread): never trust working_directory for mutations — use git -C <abs-path> … (or inline cd <abs-path> && …) and assert git rev-parse --show-toplevel + branch name in the same command, failing closed before any destructive op.

Would be great to see the fix explicitly cover the mutating/approval-gated path and worktrees, and to have the Current directory: footer reflect a real post-command pwd.