[Bug] File-change attribution asymmetry between concurrent sessions

Status Open
Reported on v2.1.272
Maintainer reply None cached
Activity 3 comments · opened Sep 15, 2026

Bug Description
Tool-call file-change attribution appears to cross sessions A Bash call rendered a second result line in the terminal: ⎿ Updated xxx/xxx.md (+5 -5) The session that displayed it made no Edit/Write/NotebookEdit call at any point — every call was read-only (cat, sed, grep, sqlite3) plus two CLI dispatch commands. The model also never received that line: its tool result contained only the command's JSON stdout. So the user sees a file change attributed to the agent, the agent has no record of it, and neither side can resolve it in conversation. This has recurred many times in one day across multiple concurrent sessions on the same machine: a modification line appears under one agent's session, the user asks that agent, the agent denies it. Repro shape: several concurrent Claude Code sessions on one machine; run a Bash command that hands off to a background daemon which writes tracked files; observe an "Updated <path> (+n -m)" line attached to that tool call while the model's own tool result contains no such line. Two candidate causes, neither verified: (a) file-change attribution leaking between concurrent sessions; (b) correct attribution of a side effect — the daemon invoked by the command writes a tracked file and it is attributed to the causing call — in which case the line is accurate AND the agent's denial is accurate, since the agent itself edited nothing. Either way the asymmetry is the defect: the user sees evidence the model cannot see, so the question "did you do that?" is unanswerable. Environment: macOS (Darwin 27.0.0), Opus 5 (1M context)

Environment Info

  • Platform: darwin
  • Terminal: tmux
  • Version: 2.1.272
  • Feedback ID: 7e5af208-d405-49f2-afea-b3c919861e8d

Errors

[]

View original on GitHub ↗

3 Comments

droppedasbaby · 22 days ago

Same issue, macOS, 2.1.270 through 2.1.280, 6 to 8 concurrent sessions in one repo.

It is your cause (a). The diff is a before/after snapshot of the whole git working tree around the Bash call, with no notion of which process wrote the file, so a concurrent session's write lands under whichever command brackets it.

Workaround: "bashEditDiffEnabled": false in ~/.claude/settings.json. Removes the rendered line and the bashEditDiff field on the tool result.

rezzminator · 20 days ago

Still present on 2.1.281 (macOS, tmux, bypassPermissions, several concurrent sessions in one repo). Confirming cause (a) with controlled tests, plus one detail that explains why it looks intermittent: whether a write is caught depends on the shape of the in-flight command, not on who wrote the file.

Every test below: a detached nohup sh -c "sleep N; echo … > <repo>/probe.txt" writer (not a Claude session) fires while the session runs one foreground Bash command. mtimes confirm each write landed inside the call's window.

| In-flight Bash command | Concurrent write | bashEditDiff on that call |
|---|---|---|
| sleep 8; echo "…$(test -f …)" | new untracked file | none |
| sleep 5; echo … | append to a tracked file | none |
| python3 -c "import time; time.sleep(12)" | new untracked file | changedFiles: [probe] |
| python3 -c "import time; time.sleep(45)" | another Claude session's Write tool creates a file | created: true for that file |

So a pure wait is credited with creating a file it never touched, while an equivalent sleep isn't snapshotted at all. It looks like some command shapes skip the before/after snapshot and others don't. From the user's side, the phantom Updated <file> lines therefore appear under some commands and not others, which makes the bug look random.

Two real incidents from the same session:

  • A Bash call (cd to a scratch dir outside the repo, then claude -p …) ran from 13:59:14.150Z to 13:59:24.746Z. Meanwhile another session's sub-agent ran git merge --ff-only (13:59:19.654Z → .879Z). The call's bashEditDiff listed 39 changedFiles, identical to git diff --name-only of that fast-forward. The UI rendered Updated docs/…/callmeter.md (+12 -8) under it.
  • A read-only pipeline (grep -n … | grep -v _test | head -20; f=$(ls …); grep -c …, 159 ms, 13:59:38.059Z → .218Z) was credited with another session's Edit-tool hunk on scripts/test-codex-sync.sh (tool_use at 13:59:38.074Z). So read-only commands aren't reliably skipped either.

As reported above, the model never sees any of this. Its tool_result held stdout only, so when the user asked "why did you change callmeter docs?" the agent could only deny, correctly, without being able to explain what the user was looking at.

Side note for anyone reproducing this headless: in 2.1.282 claude -p, bashEditDiff was null even for the session's own Bash write, so the affected session has to be interactive.

Workaround confirmed from the comment above: "bashEditDiffEnabled": false. Suggested fix: attribute only writes from the command's own process tree, or render the line as "changed on disk during this command (writer unknown)" rather than Updated, and put the same line in the model's tool_result so both sides see the same evidence.

levu42 · 20 days ago

I'm encountering the same. I have two sessions going on, one is changing code, another is investigating some stuff, I see the diffs from the session changing code in the session investigating stuff.