[BUG] Linux: bashEditDiff shows a concurrent Claude session's edits, including ones made before the command started

Status Open
Reported on v2.1.268
Maintainer reply None cached
Activity 4 comments · opened Sep 25, 2026

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 shows
Updated <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

  1. Open two sessions in the same repo, A and B.
  2. In A, create or read CROSS_TALK.md.
  3. 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

  1. While it runs, have B append a line with its Bash tool:

echo "from B" >> CROSS_TALK.md

  1. A's Bash result shows Updated CROSS_TALK.md with 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

View original on GitHub ↗

3 Comments

YevheniiKotyrlo · 16 days ago

Same here on Windows 11 (10.0.26200) with 2.1.283 in bypassPermissions mode, with several sessions in one checkout. The sessions ran under different CLAUDE_CONFIG_DIRs; sharing the working tree is enough.

What I measured, in case it helps:

  • One edit shows up under several sessions. A script in one session rewrote a docs file. That session's result showed the change, and so did command results in three other sessions running at the time. One of those was a prettier --write on three files, and its result listed five changed files, only one of them its own.
  • Read-only commands get it too. A command that only ran sed -n to print file excerpts showed another session's edit. On Windows, at least, it isn't limited to commands that write.
  • It reaches the model, not just the screen. The diff stays out of the tool result, but staleReadFileStateHint doesn't. After a prettier --write on 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."
  • Scale. In my transcripts since 2.1.269 (16 days), 8,042 Bash results carried 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": false in settings.json.

gnutix · 9 days ago

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.

hazyhaar · 5 days ago

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:

git init fuite && cd fuite && printf 'l1\nl2\n' > journal.txt && git add journal.txt && git commit -m init
mkdir .claude && echo '{"bashEditDiffEnabled": true}' > .claude/settings.json
claude --dangerously-skip-permissions --model haiku
# prompt: run `echo debut`, then `python3 -c "import time; time.sleep(8); print('fini')"`, as two Bash calls
# from another shell while the second command sleeps:
printf 'SECRET-EXTERNE written by another process\n' >> journal.txt

Result: ⎿ Updated journal.txt (+1 -0) with the external line, and toolUseResult.bashEditDiff plus changedFiles in 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 to QUESTIONS.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, echo alone 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: changedFiles is also handed to PostToolUse Bash hooks (see the bashEditDiffEnabled setting 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.

Showing cached comments. Read the full discussion on GitHub ↗