claude-code - 💡(How to fix) Fix [BUG] Claude Desktop 1.3109.0 (post-rewrite): Write/Edit tools silently fail to flush to disk mid-session — stale in-memory cache diverges from disk

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

In Claude Desktop 1.3109.0 (post-rewrite), the Write and Edit tools intermittently report success when the file on disk is unchanged. The tool's internal file-state cache diverges from the real filesystem, and subsequent Read/Edit/Grep calls return the cached representation, so the divergence is invisible from inside the tool loop. Only a Bash cross-check (cat, wc -l, md5sum, git status) reveals it.

This symptom-matches the older pre-rewrite report #40227, but Anthropic rewrote the Desktop app a few days before this session, so I'm filing fresh rather than reviving an inactive thread against a different codebase. Treat the overlap as "may be the same underlying bug that survived the rewrite, or a regression with identical symptoms" — investigators have better tools to tell the difference.

Error Message

2. Edit fails with a wrong error because its view is stale

  1. If they don't match, return a concrete error (WRITE_NOT_PERSISTED: disk state unchanged after write) instead of the current success string
  2. Let the agent decide what to do — retry, fall back to Bash, escalate to the user — based on a real error rather than a false success

Root Cause

2. Edit fails with a wrong error because its view is stale

Fix Action

Fix / Workaround

Mitigation I adopted for the rest of the session

RAW_BUFFERClick to expand / collapse

Summary

In Claude Desktop 1.3109.0 (post-rewrite), the Write and Edit tools intermittently report success when the file on disk is unchanged. The tool's internal file-state cache diverges from the real filesystem, and subsequent Read/Edit/Grep calls return the cached representation, so the divergence is invisible from inside the tool loop. Only a Bash cross-check (cat, wc -l, md5sum, git status) reveals it.

This symptom-matches the older pre-rewrite report #40227, but Anthropic rewrote the Desktop app a few days before this session, so I'm filing fresh rather than reviving an inactive thread against a different codebase. Treat the overlap as "may be the same underlying bug that survived the rewrite, or a regression with identical symptoms" — investigators have better tools to tell the difference.

Environment

  • App: Claude Desktop 1.3109.0 (post-rewrite)
  • Mode: Claude Code inside the Desktop app
  • OS: macOS (Apple Silicon)
  • Session date: 2026-04-20
  • Session length: ~70 minutes, auto mode active
  • Context: single git worktree, normal Bash + Write + Edit + Read flow

What I observed

1. Write reports success, disk is unchanged

After an earlier sequence of successful edits, Write on an existing tracked file began returning:

The file ... has been updated successfully. (file state is current in your context — no need to Read it back)

…repeatedly. cat and wc -l via Bash showed the disk file completely unchanged. Every subsequent Write attempt reported the same success with no disk mutation. The file's mtime also did not advance.

2. Edit fails with a wrong error because its view is stale

Calling Edit on the same file returned:

String to replace not found in file

…even though the old_string was obviously present in the disk file. The reason: Edit was matching against the tool's cached representation (which reflected an earlier failed Write, not disk), so its view disagreed with reality.

3. Read returns the cached representation, not disk

Read, Grep, and the tool's diff-output all returned content consistent with the stale in-memory cache, not with disk. This is the dangerous part — there is no way to detect the divergence from inside the Write/Edit/Read loop. I only caught it because I ran wc -l via Bash out of paranoia and the number did not match what I thought I had written.

4. Sentinel test to confirm

  1. Deleted the file entirely via Bash rm
  2. Called Write with 2 lines of content — tool reported success
  3. lsfile does not exist
  4. Tool's internal state thinks a 2-line file exists at that path

5. Bash writes always work

Every fallback via Bash (cat > file <<'EOF' ... EOF, inline python3 <<'PYEOF' ..., sed -i '', echo > file) persisted reliably to disk. The divergence is specific to the Write and Edit tools' write path.

Reproduction hypothesis (unconfirmed, correlation only)

In my session the divergence appeared to start after this kind of sequence:

  1. Write creates/updates file A successfully; tool cache matches disk
  2. Bash truncates or overwrites A (: > A, cp backup A, cat > A <<'EOF' ...)
  3. Tool cache is now stale — still remembers the pre-Bash content
  4. Next Write on A reports success but does not flush to disk
  5. All subsequent Write / Edit / Read on A operate on the stale cache forever

I cannot prove the Bash interleaving is the trigger — I didn't minimize — but it correlates with when I started seeing silent failures. A plausible model: the tool caches file contents for performance and does not invalidate the cache when an external process (Bash) mutates the file, so its write path believes it is producing a no-op or a safe overwrite when it is actually writing stale content (or writing nothing at all because the internal diff is empty).

Impact

I burned ~40 minutes of wall time debugging this. Had I committed without cross-checking with Bash, I would have pushed an empty file or a file with stale content to a tracked branch. The tool's confident success message plus the Read/Grep tools returning the cached in-memory content created a coherent false reality — I genuinely thought my writes were succeeding.

Any agentic workflow that trusts the Write/Edit return value (which is all of them) will silently ship broken work without manual cross-checks. For long autonomous sessions this is a data-loss-class bug.

Mitigation I adopted for the rest of the session

  • After every Write: wc -l <path> + grep -c <unique-new-token> <path> via Bash before continuing
  • For large new files: skipped Write entirely, used Bash heredocs from the start
  • For targeted edits on existing files: used sed or inline Python via Bash instead of Edit
  • Committed a "verify-Write/Edit-on-disk" rule into the project's CLAUDE.md so future sessions in that repo pick it up

Suggested short-term fix

Even without solving the root cause, the tool could convert silent failure into loud failure:

  1. After Write/Edit attempts a flush, stat the file and compare size + mtime against what the tool intended
  2. If they don't match, return a concrete error (WRITE_NOT_PERSISTED: disk state unchanged after write) instead of the current success string
  3. Let the agent decide what to do — retry, fall back to Bash, escalate to the user — based on a real error rather than a false success

Bonus: invalidate the cache whenever Bash (or any other tool) is observed writing to a path the cache holds, so Edit/Read don't serve stale content after a cat > or sed -i.

Cross-references

  • #40227 — same symptoms, pre-rewrite Desktop; I commented there earlier in this session before realizing we're on the rewrite
  • #5178 — "Edit tool reports false success" (older)
  • #43588 — "Sub-agent file writes lost" (related scope, sub-agents)
  • #46470 — "Agent tool with isolation:worktree silently discards all file changes on cleanup" (related scope, isolation)

Happy to provide more session detail, session IDs, or a minimal repro attempt if useful.

Reporter update: persistent across many sessions

The user whose worktree hosted the session just confirmed they've independently observed this pattern across multiple separate sessions, not just the one documented above. Specifically: Claude reports that file edits have been made, they proceed assuming the tool's success message is accurate, and they later discover (sometimes much later, sometimes only when a reviewer catches it) that the file on disk was never actually modified. They catch it in review / during next-session audits rather than in-session.

This is not a one-off glitch or an interaction effect with my specific Bash sequence — it's a recurring behavior. The session I documented above is just the one where I happened to cross-check with wc -l and catch it live. In the ambient case, the divergence compounds silently until someone happens to look at git diff / the real file / a cold checkout.

The compounding aspect matters for severity. An autonomous agent that trusts Write + Edit return values AND uses Read/Grep for its own verification (because both read from the stale cache) has no way to catch the divergence without an explicit Bash cross-check. Many real agentic workflows — including plan execution, code review automation, doc updates — do exactly that. Those workflows will silently ship phantom work and only discover it when a human looks at the actual commit or a fresh session reads the file from disk.

extent analysis

TL;DR

The most likely fix is to modify the Write and Edit tools to stat the file after attempting a flush and compare its size and mtime against the intended changes, returning an error if they don't match.

Guidance

  • Investigate the file-state cache invalidation mechanism to ensure it correctly updates when external processes like Bash modify the file.
  • Consider implementing a cache invalidation mechanism that observes changes made by other tools, such as Bash, to prevent serving stale content.
  • Modify the Write and Edit tools to perform a post-flush check, comparing the file's size and mtime against the intended changes, and return an error if they don't match.
  • Review the agent's workflow to ensure it can handle errors returned by the Write and Edit tools, such as retrying or falling back to Bash.

Example

import os

def write_file(path, content):
    # Attempt to write the file
    try:
        with open(path, 'w') as f:
            f.write(content)
    except Exception as e:
        # Handle write error
        return False

    # Stat the file to check if the write was successful
    try:
        stat_before = os.stat(path)
    except FileNotFoundError:
        # File does not exist, write failed
        return False

    # Compare the file's size and mtime against the intended changes
    if stat_before.st_size != len(content) or stat_before.st_mtime != os.stat(path).st_mtime:
        # Write failed, return an error
        return False

    # Write successful, return success
    return True

Notes

The provided example is a simplified illustration of the post-flush check and may need to be adapted to the actual implementation of the Write and Edit tools. Additionally, the cache invalidation mechanism should be reviewed to ensure it correctly handles changes made by external processes.

Recommendation

Apply the suggested short-term fix by modifying the Write and Edit tools to perform a post-flush check and return an error if the file's size and mtime don't match the intended changes. This will convert silent failures into loud failures, allowing the agent to handle the error and prevent data loss.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix [BUG] Claude Desktop 1.3109.0 (post-rewrite): Write/Edit tools silently fail to flush to disk mid-session — stale in-memory cache diverges from disk