anthropics / anthropics/claude-code
[BUG] Bash cd-compound-read guard prompts on absolute cd targets whenever a Read() deny rule exists (Windows Git Bash, 2.1.257-2.1.259)
- Dominant language
- Python
- Stars
- 145k
- Forks
- 23.1k
- PR merge metrics
- PR metrics pending
Description
## Environment
- Claude Code 2.1.259 native install (2.1.257 and 2.1.258 binaries on the same machine reproduce it), Windows 11 Pro 10.0.26200, Git Bash as the Bash tool shell
- `permissions.defaultMode: auto`; user settings carried six `Read()` deny rules: `Read(.env)`, `Read(**/.env)`, `Read(**/.env.*)`, `Read(**/credentials*)`, `Read(**/*.pem)`, `Read(**/*.key)`, plus Bash and Edit denies
## What happens
Any compound Bash command that contains `cd` and a `;`, or `cd && grep -r `, stops for approval on every relative-path read, even when the cd target is an absolute literal path:
> sed reads a file by a relative path after a cd in a compound command; which file that is cannot be resolved statically while a Read() deny rule is configured, so this needs approval.
Decision reason: `Compound command contains cd with a relative file read while a Read() deny rule exists`, `bashMissKind: "cd-compound-read"`.
The prompt appears in auto mode and, as observed by the operator, in bypass-permissions mode. Subagent Bash calls surface it as a manual approval in the parent session, so with several subagents running it was one prompt per file read.
## Measured matrix
Headless probes with `claude -p --permission-mode auto --model haiku --tools Bash`, exact tool input captured from `--output-format stream-json`, working directory equal to the cd target. Same settings for every row.
| Command (2.1.259) | Result |
|---|---|
| `cd D:/dev/ && sed -n 1,2p README.md` | allowed |
| `cd D:/dev/ && sed -n 1,2p README.md; echo ===` | prompt, cd-compound-read |
| `cd D:/dev/; sed -n 1,2p README.md` | prompt, cd-compound-read |
| `cd D:/dev/ && grep -rn pat sub/dir/ \| head -2` | prompt: "grep on 'sub/dir/' after a cd would search a directory that cannot be determined here, and a Read() deny rule is configured" |
| `sed -n 1,2p README.md` | allowed |
2.1.258: the `&& sed …; echo …; grep -r …` and `&& grep -r sub/dir/ \| head` shapes prompt with the cd-compound-read wording; the pure `&& sed` chain is allowed. The guard's code is identical across the 2.1.257, 2.1.258 and 2.1.259 binaries apart from minified identifiers; I have no older binary to date its introduction. Prompts began for us between 2.1.257 (installed Sep 1) and 2.1.259 (Sep 2).
## Observations
- The cd target is an absolute literal in every prompting case, so "cannot be resolved statically" does not hold. The resolver appears to give up whenever the compound contains `;`, including for a read that sits before the `;` in the `&&` chain and therefore runs under the known directory.
- The grep wording on 2.1.259 names the wrong operand. `cd /d/dev/ && echo "=== X ==="; grep -rn "X" --include=*.cs .` produced "grep on '--include=*.cs' after a cd would search a directory that cannot be determined here". The search path is `.`.
- Removing the six `Read()` deny rules from user settings stopped the prompts in the interactive sessions at once (settings reload live). In headless `-p --permission-mode auto` the same command still prompts with every `Read()` and `Edit()` rule removed from user and project settings, so something else arms the check there; I could not identify what.
- Headless `-p --dangerously-skip-permissions` allowed every shape on 2.1.258 and 2.1.259.
## Expected
A `cd` to an absolute literal path followed by relative reads is resolvable, and the guard already resolves it for the pure `&&` chain. A `;` later in the compound should not un-resolve a read that runs under the `&&`. The grep wording should name the actual path operand.
## Related
#86619 covered the write-side variant of the same cd-compound analysis on Windows Git Bash (fixed in 2.1.233). This is the read side, keyed on the presence of `Read()` deny rules.
Contributor guide
No contributing guide indexed for this repository
Research direction
Reproduce the supplied command matrix in Windows Git Bash, focusing on the cd-compound-read guard and its behavior with Read() deny rules. Compare the read-side analysis with related issue #86619; done means absolute cd targets remain resolvable despite later semicolons, and grep prompts identify the actual search path.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- bash
- Domain
- cli, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100