[BUG] Linux: bashEditDiff shows a concurrent Claude session's edits, including ones made before the command started
Related
This looks related to #95854 (same misattribution, but caused by a separate writer process on macOS)
and #94571 (the model can't see the diff). This report adds: Linux, two Claude sessions as
the writers, a diff that includes changes made before the command started, and a
read-only command not triggering it.
What happens
Two Claude Code sessions are running in the same git checkout. Session A runs a Bash
command that writes something unrelated, such as a file in /tmp. Session B edits a
file in the repo that A has seen before. A's Bash result then showsUpdated <file> (+N -M) with B's diff under it, as if A's command had made the edit.
The diff is saved in A's transcript (toolUseResult.bashEditDiff) but not in the
tool result sent to the model. It only clutters the display and the saved transcript.
Expected
A Bash command's result lists only changes that command made. At the least, it shouldn't
credit a command with changes made before it started.
Findings
- It only appears after commands that write. Watcher commands that only read
(until grep …; do sleep 1; done) never showed the edit. The same watcher with
cat > /tmp/probe.txt <<EOF … EOF in front of it showed it every time.
- The diff isn't limited to the command's run. It compares against the last
version of the file the session saw, not against the file as it was when the command
started. In the reproduction below, the command ran from 14:13:47 to 14:14:01. Only one
line was added in that time, but the diff showed four, including three added earlier
while no command in A was running.
- Whether git tracks the file doesn't matter. It happened with a tracked ADR file and
an untracked scratch file.
- It first appeared in v2.1.269. Across my local transcripts there are no non-empty
bashEditDiff entries in 2.1.268 or earlier.
Reproduce
- Open two sessions in the same repo, A and B.
- In A, create or read
CROSS_TALK.md. - In A, run a Bash command that writes somewhere and then waits:
cat > /tmp/probe.txt <<'EOF' / x / EOF, then
n=$(wc -l < CROSS_TALK.md); until [ "$(wc -l < CROSS_TALK.md)" -gt "$n" ]; do sleep 1; done
- While it runs, have B append a line with its Bash tool:
echo "from B" >> CROSS_TALK.md
- A's Bash result shows
Updated CROSS_TALK.mdwith B's line. It also shows any lines
added earlier that A hadn't seen yet.
Why it matters
Anyone running several sessions in parallel in one checkout sees other sessions' diffs
under unrelated commands in every session. That makes the transcript misleading about
which command changed what.
Workaround
"bashEditDiffEnabled": false in ~/.claude/settings.json (or CLAUDE_CODE_BASH_EDIT_DIFF).
It's on by default in auto/bypassPermissions mode, which is why it showed up for me.
Environment
- Claude Code 2.1.282 (first seen on 2.1.281; appears from 2.1.269)
- Linux 7.0.0, terminal CLI, auto permission mode
Showing cached comments. Read the full discussion on GitHub ↗
3 Comments
Same here on Windows 11 (10.0.26200) with 2.1.283 in
bypassPermissionsmode, with several sessions in one checkout. The sessions ran under differentCLAUDE_CONFIG_DIRs; sharing the working tree is enough.What I measured, in case it helps:
prettier --writeon three files, and its result listed five changed files, only one of them its own.sed -nto print file excerpts showed another session's edit. On Windows, at least, it isn't limited to commands that write.staleReadFileStateHintdoesn't. After aprettier --writeon two files plus lint and a type-check, the model got "This command modified 1 file you've previously read: <an unrelated file another session was editing>. Call Read before editing."bashEditDiff. In 2,311 of them (29%), a listed file had been edited through Edit/Write by another session while the command ran; on busy days, over 60%. That undercounts: it leaves out changes other sessions made through their own commands.The UI already has a caveat for overlapping commands, "(another command ran in this repository at the same time; a change made by either may show under either result)". Showing it when another live session is working in the same repository would clear up most of the confusion.
For now I've turned it off with
"bashEditDiffEnabled": falseinsettings.json.Also seeing this on NixOS (Linux 6.18) with Claude Code 2.1.287: several interactive sessions in the same checkout, and edits made by one session show up as
Updated <file> (+N -M)diffs under unrelated tool calls in the others.Same mechanism reproduced on Linux, Claude Code 2.1.295, with two additions to this thread.
1. Isolated reproduction without a second Claude session. A plain external process writing to a tracked file while a Bash command runs is enough. Full write-up, transcript excerpt and an automated driver (python
pty+pyte) are in https://github.com/anthropics/claude-code/issues/100719#issuecomment-6076986464. Short form:Result:
⎿ Updated journal.txt (+1 -0)with the external line, andtoolUseResult.bashEditDiffpluschangedFilesin the transcript for a command that opened no file.2. The "only commands that write trigger it" finding does not hold. In our transcripts a read-only pipeline (
cd …; grep … | cut … | head) got credited with another session's edit toQUESTIONS.md, and a command run in a scratch directory outside the repo (cd /tmp/…; pip install …) got credited with three repo files edited by two other sessions. What the code (extracted from the 2.1.295 binary) actually does: before each Bash command it builds a tree object of the whole repository working tree in a private objects directory (commit-tree), builds another one afterwards and diffs the two. The only exemptions are commands classified as trivial (sleep,echoalone never produced a snapshot in our runs) and the first Bash call of a session. Nothing scopes the diff to the command's own process tree, so any concurrent writer in the checkout is attributed to it.A consequence not yet listed here:
changedFilesis also handed to PostToolUse Bash hooks (see thebashEditDiffEnabledsetting description), so a hook that lints, stages or reverts "the files this command changed" acts on another session's work.#100719 (same reporter as this comment) is the same defect seen from the other terminal and can be treated as a duplicate of this one.