Skip to content

Edit tool returns "File has been unexpectedly modified" when file is NOT modified #12462

Closed as duplicate

Description

@FrancescoB2024

Preflight Checklist

  • I have searched existing issues and this hasn't been reported yet
  • This is a single bug report (please file separate reports for different bugs)
  • I am using the latest version of Claude Code

What's Wrong?

Bug Description

The Edit tool repeatedly returns error "File has been unexpectedly modified. Read it again before attempting to write
it." even when no external process is modifying the file.

Steps to Reproduce

  1. Read a file with the Read tool
  2. Immediately attempt to Edit the file
  3. Error appears despite no changes to the file

Verification

  • Verified with certutil -hashfile <file> MD5 - hash remains identical between reads
  • No Python, VS Code, or other editor processes running
  • No cloud sync (OneDrive/Dropbox) active
  • File is on local SSD (E: drive)

Environment

  • Windows 10/11
  • Claude Code CLI
  • Local filesystem (not network/cloud)

Workaround

Using Python directly to modify files:

with open('file.py', 'r', encoding='utf-8') as f:
    content = f.read()
content = content.replace('old', 'new')
with open('file.py', 'w', encoding='utf-8') as f:
    f.write(content)

Impact

- Blocks normal workflow
- Requires workarounds
- Very frustrating when it persists across 10+ attempts

### What Should Happen?

1. Read a file with the Read tool
2. Immediately attempt to Edit the file
3. Error appears despite no changes to the file

### Error Messages/Logs

```shell
Update(qt_slideshow_util2.py)
⎿  Error: File has been unexpectedly modified. Read it again before attempting to write it.

Steps to Reproduce

  1. Read a file with the Read tool
  2. Immediately attempt to Edit the file
  3. Error appears despite no changes to the file

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

No response

Claude Code Version

2.0.54 (Claude Code)

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

Windows Terminal

Additional Information

Ciao frm Italy to Dario and Daniela Amodei

Activity

  1. ryancogswell commented on Nov 27, 2025

    @ryancogswell

    Seeing this same problem. Started 11/26/2025 and continuing 11/27. Claude Code version 2.0.55.

    Platform: Windows (MINGW64_NT-10.0-20348)

    Claude Opus tried several different ways to edit the file (sed, full re-write of file) that failed with the same or equivalent error. It was successful using python to do the file edits.

  2. visma-mrange commented on Nov 28, 2025

    @visma-mrange

    I will just add I am seeing this as well. Running Windows 11. Claude Code 2.0.55. Running in a powershell terminal. I see no edits to the file claude complains about being edited.

  3. Exzyle-lab commented on Nov 29, 2025

    @Exzyle-lab

    Environment:
    Claude Code VSCode Extension
    Windows 10/11
    Directory: D:/Projects/RPGs/Arcanum/[SYS] Memory Bank/
    Files affected: 01_State.md, 02_Log.md
    Reproduction:
    Read file using Read tool — succeeds
    Attempt Edit tool on same file — fails with "File has been unexpectedly modified"
    Re-read file — succeeds
    Re-attempt Edit — fails again with same error
    Loop continues indefinitely regardless of retries
    Diagnostics performed:
    Restarted IDE — no effect
    Restarted computer — no effect
    Removed read-only file attributes via PowerShell — no effect
    Verified no cloud sync (disabled Google Drive sync, killed GDrive/OneDrive processes)
    Ran disk check — no errors
    Verified basic write access works (echo "test" > test_write.txt succeeds)
    No other processes holding file locks
    Key observation: Basic file I/O works fine. The issue is isolated to the Edit tool's internal cache/comparison mechanism. The tool appears to compare against a stale cached version rather than the actual file on disk. Workaround used: Bypassed Edit tool entirely using sed -i for inline text replacement. All edits completed successfully via bash, confirming this is an Edit tool-specific issue, not a system-level file access problem. Versions tested: This session occurred on 2025-11-29. Issue persisted through multiple IDE restarts and a full computer reboot.

  4. ryancogswell commented on Dec 1, 2025

    @ryancogswell

    Not certain this is related, but I'm mainly seeing this issue repeat when Opus is editing files within a skill. I also get prompted with every edit for skills even when I select #2 to accept all edits. Perhaps a permissions bug rather than a cache bug?

  5. ryancogswell commented on Dec 4, 2025

    @ryancogswell

    Uninstalling Claude Code and reinstalling it, seems to have resolved the issue for me (none of these errors in the last day).

  6. erwinh22 commented on Dec 6, 2025

    @erwinh22

    Cross-referencing: A verified fix for this issue has been posted at #12805 (comment) - patches the timestamp validation logic in cli.js to bypass the broken Windows detection.

  7. davidrimshnick commented on Dec 17, 2025

    @davidrimshnick

    Just hit this bug again on Windows/MINGW. Workaround was using cat > file << 'EOF' via Bash instead of the Edit tool.

    Hypothesis on root cause: I suspect CRLF line ending normalization is the culprit.

    Git on Windows often has core.autocrlf=true, which converts LF <-> CRLF. If the Read tool normalizes content to LF internally when storing/hashing, but the Edit tool re-reads the raw file (which has CRLF on disk) before comparing, the hashes won't match - triggering a false "file has been unexpectedly modified" error.

    A potential fix would be to normalize line endings before hashing, or use a content comparison that's line-ending agnostic.

    Environment: Windows 10, MINGW64_NT-10.0-17763, Git Bash

  8. kevinjbradshaw commented on Dec 24, 2025

    @kevinjbradshaw

    Really need to get on this. It makes claude borderline unusable!

  9. davidrimshnick commented on Dec 24, 2025

    @davidrimshnick
  10. LiangMu-Studio commented on Dec 30, 2025

    @LiangMu-Studio

    Root Cause Analysis & Workaround

    I analyzed the Claude Code source code and found the root cause.

    Root Cause

    Claude Code uses file system timestamps (mtimeMs) instead of content hashes to detect file changes. This causes false positives when cloud sync tools (Dropbox, OneDrive), IDE auto-save, or antivirus software touch file metadata without changing content.

    Workaround: PreToolUse Hook with Content Hashing

    I created a hook that uses SHA256 content hashing instead of timestamps.

    Setup:

    1. Create ~/.claude/hooks/PathValidation.ps1
    2. Add hook config to ~/.claude/settings.json
    Click to expand: settings.json
    {
      "hooks": {
        "PreToolUse": [
          {
            "matcher": "Read|Write|Edit|NotebookEdit",
            "hooks": [
              {
                "type": "command",
                "command": "pwsh -NoProfile -ExecutionPolicy Bypass -File \"%USERPROFILE%\\.claude\\hooks\\PathValidation.ps1\""
              }
            ]
          }
        ]
      }
    }
    Click to expand: PathValidation.ps1 (full script)
    # PathValidation.ps1 - File sync validation hook
    # Uses content hash instead of timestamp to detect real changes
    
    param()
    
    $CacheFile = "$env:USERPROFILE\.claude\hooks\.file_cache.json"
    $LogFile = "$env:USERPROFILE\.claude\hooks\.hook.log"
    
    function Write-Log($msg) {
        $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
        "$timestamp - $msg" | Add-Content $LogFile -ErrorAction SilentlyContinue
    }
    
    function Get-FileHash256($path) {
        if (-not (Test-Path $path -ErrorAction SilentlyContinue)) { return $null }
        try {
            return (Get-FileHash -Path $path -Algorithm SHA256 -ErrorAction Stop).Hash
        } catch { return $null }
    }
    
    function Get-Cache {
        if (Test-Path $CacheFile -ErrorAction SilentlyContinue) {
            try { return Get-Content $CacheFile -Raw -ErrorAction Stop | ConvertFrom-Json -AsHashtable }
            catch {}
        }
        return @{}
    }
    
    function Save-Cache($cache) {
        try { $cache | ConvertTo-Json -Depth 10 -Compress | Set-Content $CacheFile -Force -ErrorAction Stop }
        catch {}
    }
    
    $inputJson = ""
    try { $inputJson = [Console]::In.ReadToEnd() } catch {}
    
    # Fix Windows path backslashes in JSON
    $inputJson = [regex]::Replace($inputJson, '(?<!\\)\\(?![\\"/bfnrtu])', '\\')
    
    try {
        $inputObj = $inputJson | ConvertFrom-Json
        $toolName = $inputObj.tool_name
        $toolInput = $inputObj.tool_input
    
        $filePath = $toolInput.file_path
        if (-not $filePath) { $filePath = $toolInput.notebook_path }
        if (-not $filePath) { $filePath = $toolInput.path }
    
        if (-not $filePath) {
            Write-Output '{"continue":true}'
            exit 0
        }
    
        $normalizedPath = [System.IO.Path]::GetFullPath($filePath)
        $cache = Get-Cache
    
        switch ($toolName) {
            'Read' {
                $hash = Get-FileHash256 $normalizedPath
                if ($hash) {
                    $cache[$normalizedPath] = @{ hash = $hash }
                    Save-Cache $cache
                    Write-Log "Read: $normalizedPath"
                }
                Write-Output '{"continue":true}'
            }
    
            { $_ -in @('Write', 'Edit', 'NotebookEdit') } {
                if (-not (Test-Path $normalizedPath -ErrorAction SilentlyContinue)) {
                    Write-Log "New file: $normalizedPath"
                    Write-Output '{"continue":true}'
                    exit 0
                }
    
                $currentHash = Get-FileHash256 $normalizedPath
                $cachedEntry = $cache[$normalizedPath]
    
                if ($cachedEntry -and $currentHash) {
                    if ($cachedEntry.hash -ne $currentHash) {
                        Write-Log "BLOCKED: $normalizedPath (content changed)"
                        Write-Output ('{"continue":false,"reason":"File content changed externally. Please re-read: ' + $normalizedPath + '"}')
                        exit 0
                    }
                }
    
                Write-Log "Allow: $normalizedPath"
                Write-Output '{"continue":true}'
            }
    
            default {
                Write-Output '{"continue":true}'
            }
        }
    
    } catch {
        Write-Log "Error: $_"
        Write-Output '{"continue":true}'
    }

    How it works

    Event Action
    Read Cache file's SHA256 hash
    Write/Edit Compare current hash with cached
    Hash matches Allow (timestamp-only change = false positive)
    Hash differs Block and prompt to re-read

    Suggested Fix

    Consider using content hashing instead of timestamps for file change detection, or as a fallback when timestamp check fails.

  11. webmasterfsd commented on Jan 1, 2026

    @webmasterfsd

    I'm getting the same error, Error: File has been unexpectedly modified. Read it again before attempting to write it.

    Actually, the issue started when the conversation has compacted automatically or manually. Once it is compacted, the issue has started.

  12. 19317362 commented on Jan 2, 2026

    @19317362

    Why Anthropics CAN NOT solve this BUG for SO LONG? It comes everyday for so many users . What's doing on this?

  13. self-assigned this
    on Jan 13, 2026
  14. github-actions commented on Feb 12, 2026

    @github-actions

    This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.

  15. bcherny commented on Aug 19, 2026

    @bcherny
    Collaborator

    Closing as a duplicate of #3513 — please follow and 👍 that issue instead so we can track it in one place. If you think this was closed in error, comment here and we'll reopen.

    🤖 Generated with Claude Code

  16. github-actions commented on Oct 9, 2026

    @github-actions

    This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.

  17. locked as resolved and limited conversation to collaborators on Oct 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:toolsbugSomething isn't workingduplicateThis issue or pull request already existshas reproHas detailed reproduction stepsplatform:windowsIssue specifically occurs on Windows

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions