anthropics / anthropics/claude-code
[BUG] Cowork: device_commit_files reports success on overwrites but the on-disk content lags exactly one commit behind (silent stale write, fresh mtime)
- Vorherrschende Sprache
- Python
- Sterne
- 145k
- Forks
- 23.1k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
### Preflight Checklist
- [x] I have searched [existing issues](https://github.com/anthropics/claude-code/issues?q=is%3Aissue%20state%3Aopen%20label%3Abug) and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
### What's Wrong?
## Summary
When a cloud Cowork session writes back to a file that **already exists** on the linked device, `device_commit_files` returns `{"written":[path],"rejected":[]}`, the file's modification time advances to the moment of the call, and **the content on disk is the payload from the previous commit**. Committing the identical payload a second time lands it.
Creating a **new** file is unaffected and correct every time. Only overwrites are affected.
This is a silent data-integrity failure. The session has no signal that anything went wrong, and the file it just "wrote" looks freshly updated to any human or tool inspecting it, because the timestamp is current while the bytes are stale.
## Impact
This is worse than a loud failure for two reasons.
1. **The success response is indistinguishable from a real write.** An agent that follows the obvious contract, commit and move on, will report work as saved that was not saved.
2. **The timestamp lies in the same direction.** A stale file carries the new write's mtime, so ordinary "has this been updated?" checks, sync tools, and human inspection all agree with the false success.
For anyone using a Cowork workspace with recurring update routines, the exposed operations are exactly the common ones: appending to a running log, updating a status line, bumping a version, editing a spec. Every one of those is an overwrite. The drift is invisible until someone reads the file much later.
## Workaround
Commit the same payload twice, then stage the file back and grep the content for the intended change. Byte count is a weak check and the timestamp is no check at all. Where possible, do write-heavy work in Claude Code instead, which writes to disk directly and does not use this path. (Confirmed clean by test on the same machine: new file, two Write-tool overwrites, and one Edit-tool in-place edit, each verified from a separate PowerShell process, all four exact with no lag.)
## Suggested area to look at
The off-by-one shape suggests something in the commit path is buffering or staging the payload and swapping in the previous one for the overwrite case, since the create case is correct. The mtime being updated from the current call while the bytes come from the prior call points at the metadata write and the content write reading from different sources.
### What Should Happen?
After `device_commit_files` returns `written` with no rejections, the file on disk should contain the committed payload. If the write cannot be completed, the call should report the path in `rejected` rather than returning success.
### Error Messages/Logs
```shell
```
### Steps to Reproduce
## Reproduction
Minimal repro, run against a plain local folder (`C:\Users\\Downloads`, **not** OneDrive-backed):
| Step | Action | Committed payload | Commit result | On disk immediately after |
|---|---|---|---|---|
| 1 | `device_commit_files` (new file) | `VERSION-A…` (43 bytes) | `written`, no rejections | **43 bytes, VERSION-A** ✅ |
| 2 | `device_commit_files` (overwrite) | `VERSION-B…` (82 bytes) | `written`, no rejections | **43 bytes, VERSION-A** ❌ (mtime advanced) |
| 3 | `device_commit_files` (same payload again) | `VERSION-B…` (82 bytes) | `written`, no rejections | **82 bytes, VERSION-B** ✅ |
| 4 | `device_commit_files` (overwrite) | `VERSION-C…` (89 bytes) | `written`, no rejections | **82 bytes, VERSION-B** ❌ (mtime advanced) |
| 5 | Wait 45 s, re-read, **no** intervening commit | — | — | **82 bytes, VERSION-B** ❌ |
Payload lengths were chosen to differ, so byte count alone distinguishes the revisions without inspecting content. Content was checked as well via `device_stage_files` and matched the byte count in every case.
## What this rules out
- **Not a read cache.** Step 5 waited 45 seconds with no intervening commit and the stale content persisted. `device_list_dir` and `device_stage_files` agreed with each other at every step.
- **Not OneDrive.** First observed on files under a OneDrive-synced folder, then reproduced identically in `C:\Users\\Downloads`, outside OneDrive entirely.
- **Not KB5124008.** That update broke the Hyper-V Plan9 shares used by `device_bash` on this machine (see #92984). The local sandbox shell was completely non-functional throughout this testing while the file bridge kept working, so the two are on different code paths.
- **Not `force`.** Behavior is identical with and without `force: true`, and with and without `expectedMtimeMs`.
## Observed elsewhere in the same session
Reproduced five separate times across four different files before it was isolated:
- two markdown files under a OneDrive-synced connected folder (~8 KB and ~65 KB), twice each
- a `.ps1` script file in the same folder
- the `Downloads` test file above
In every case the pattern was the same: first commit reports success and leaves the prior revision, second identical commit lands the new content.
### Claude Model
Opus
### Is this a regression?
Yes, this worked in a previous version
### Last Working Version
_No response_
### Claude Code Version
Claude Desktop | 1.49585.0 |
### Platform
Anthropic API
### Operating System
Windows
### Terminal/Shell
Other
### Additional Information
## Environment
| | |
|---|---|
| Claude Desktop | 1.49585.0 |
| Platform | win32 x64 |
| Electron / Node | 44.2.0 / 24.20.0 |
| OS | Windows 11 25H2, OS Build 26200.9445 |
| Session type | Cowork **cloud** session linked to a desktop device |
| Model | claude-opus-5 |
## Related Issue
This may be related to: https://github.com/anthropics/claude-code/issues/83354
Beitragsleitfaden
Für dieses Repository ist kein Beitragsleitfaden indexiert
Rechercherichtung
Start at the device_commit_files entry point and compare its overwrite path with device_stage_files and device_list_dir using the Windows reproduction steps. Verify that each successful overwrite leaves the committed payload on disk immediately, and that failed writes are reported in rejected rather than written.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- electron, node.js
- Bereich
- api, desktop
- Issue-Typ
- Bug
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Aktivitätsstatus
- Aktiv
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 48/100