claude-code icon indicating copy to clipboard operation
claude-code copied to clipboard

[Bug] Anthropic API Error: Incomplete Tool Invocation Response

Open JosiahSiegel opened this issue 3 months ago • 5 comments

Bug Description Edit Tool Path Format Issue on Windows

Environment Info

  • Platform: win32
  • Terminal: windows-terminal
  • Version: 1.0.117
  • Feedback ID: 68b09737-0121-4b35-b444-9ee5f7fe27ea

Executive Summary

The Edit and MultiEdit tools fail with "File has been unexpectedly modified" error on Windows when using forward slashes in file paths for the initial file access. This creates a confusing user experience where the same command fails initially but works after a successful edit using backslashes.

Bug Details

Environment

  • Platform: Windows (MINGW64_NT-10.0-26100)
  • Claude Code Version: Current as of 2025-09-20
  • Affected Tools: Edit, MultiEdit

Issue Description

When attempting to edit a file on Windows using forward slashes (/) in the file path, the tools fail with:

Error: File has been unexpectedly modified. Read it again before attempting to write it.

Reproduction Steps

  1. Create or identify a file that has never been edited in the current session
  2. Read the file using: Read(file_path: "D:/path/to/file.tsx")
  3. Attempt to edit using: Edit(file_path: "D:/path/to/file.tsx", ...)
  4. Result: Fails with "unexpectedly modified" error
  5. Read again using backslashes: Read(file_path: "D:\path\to\file.tsx")
  6. Edit using backslashes: Edit(file_path: "D:\path\to\file.tsx", ...)
  7. Result: Success
  8. Subsequent edits with forward slashes now work

Root Cause Analysis

File State Cache Issue

The Edit tool maintains an internal file state cache that:

  1. Fails to initialize properly when first accessing a file with forward slashes on Windows
  2. Cannot match the file identity between forward slash and backslash representations
  3. Once properly initialized (via backslash access), accepts both formats
  4. Persists during the session, making previously "fixed" files work with both formats
Path Normalization Inconsistency
  • Input paths: Accept both D:/path/file and D:\path\file
  • Internal tracking: Fails to normalize paths before comparing
  • Display output: Always shows normalized backslashes (e.g., Update(path\to\file))
  • File system operations: Work correctly with both formats

Test Results

Scenario File State Path Format Result
New file, first edit Never edited Forward slash (D:/...) ❌ FAILS
New file, first edit Never edited Backslash (D:\...) ✅ WORKS
Same file, second edit Previously edited Forward slash (D:/...) ✅ WORKS
Same file, second edit Previously edited Backslash (D:\...) ✅ WORKS
Copied file, first edit Never edited Forward slash (D:/...) ❌ FAILS
Copied file, first edit Never edited Backslash (D:\...) ✅ WORKS

Verified File Attributes

The following attributes were checked and ruled out as causes:

  • ✅ File permissions (644, normal)
  • ✅ File encoding (UTF-8 without BOM)
  • ✅ Line endings (Unix \n and Windows \r\n both tested)
  • ✅ Git status (both tracked and untracked files affected)
  • ✅ Symlinks (not a factor)
  • ✅ NTFS metadata (no alternate data streams)
  • ✅ File timestamps (not being modified externally)
  • ✅ File locks (no processes holding locks)

Impact

User Experience Issues
  1. Inconsistent behavior: Same command works sometimes but not others
  2. Misleading error message: "File has been unexpectedly modified" suggests external changes when none occurred
  3. Confusing output: Display always shows backslashes, making it unclear what format was used
  4. Workflow disruption: Users must remember to use backslashes for initial edits
Technical Issues
  1. Path format dependence: Tool behavior shouldn't depend on slash direction on Windows
  2. State management bug: File cache initialization fails with valid paths
  3. Poor error messaging: Error doesn't indicate the actual problem

Recommended Fixes (Suggestions from Claude, not me)

Priority 1: Normalize Paths on Input

# Pseudo-code for fix
def normalize_path(path):
    # On Windows, convert all paths to use native separators
    if platform == 'windows':
        return path.replace('/', '\\')
    return path

def edit_file(file_path, ...):
    normalized_path = normalize_path(file_path)
    # Use normalized_path for all operations and cache keys

Priority 2: Fix File State Cache

  • Ensure file state cache uses normalized paths as keys
  • Initialize cache properly regardless of input path format
  • Consider using os.path.normpath() or equivalent for all path operations

Priority 3: Improve Error Messages

Instead of: "File has been unexpectedly modified" Suggest: "File state tracking error. Try using Windows path format (backslashes) or re-read the file"

Priority 4: Add Path Format Validation

  • Warn users on Windows when mixing path formats
  • Provide clear guidance in documentation about path format requirements

Workarounds (Current)

For users experiencing this issue:

  1. Always use backslashes on Windows: D:\path\to\file
  2. For existing files showing errors:
    • Read with backslashes first
    • Then edit with backslashes
    • Subsequent edits can use either format
  3. Alternative: Use Write tool for complete file replacement (though not ideal for small edits)

Additional Notes

  • The issue is specific to Windows environments
  • The Read tool works correctly with both path formats
  • The Write tool (for new files) works correctly with both formats
  • The issue only affects the Edit and MultiEdit tools
  • Once a file has been successfully edited with backslashes, it remains "unlocked" for the session

Test Code to Reproduce

// This will fail on Windows with forward slashes (first attempt)
Read(file_path: "D:/repos/test/example.tsx")
Edit(file_path: "D:/repos/test/example.tsx", old_string: "foo", new_string: "bar")
// Error: File has been unexpectedly modified

// This will succeed
Read(file_path: "D:\\repos\\test\\example.tsx")
Edit(file_path: "D:\\repos\\test\\example.tsx", old_string: "foo", new_string: "bar")
// Success

// Now forward slashes work for this file
Edit(file_path: "D:/repos/test/example.tsx", old_string: "bar", new_string: "baz")
// Success

JosiahSiegel avatar Sep 20 '25 14:09 JosiahSiegel

It can temporarily be fixed by entering this as a prompt: "There's a file modification bug in Claude Code. The workaround is: always use complete absolute Windows paths with drive letters and backslashes for ALL file operations. Apply this rule going forward, not just for this file."

SShadowS avatar Sep 20 '25 21:09 SShadowS

I place this workaround in CLAUDE.md and it has worked so far:

## CRITICAL: File Editing on Windows

### ⚠️ MANDATORY: Always Use Backslashes on Windows for File Paths

**When using Edit or MultiEdit tools on Windows, you MUST use backslashes (`\`) in file paths, NOT forward slashes (`/`).**

#### ❌ WRONG - Will cause errors:
```
Edit(file_path: "D:/repos/project/file.tsx", ...)
MultiEdit(file_path: "D:/repos/project/file.tsx", ...)
```

#### ✅ CORRECT - Always works:
```
Edit(file_path: "D:\repos\project\file.tsx", ...)
MultiEdit(file_path: "D:\repos\project\file.tsx", ...)
```

JosiahSiegel avatar Sep 26 '25 11:09 JosiahSiegel

Validation & Corrections from Isolated Testing

I've conducted comprehensive isolated testing that confirms the cache poisoning bug and provides additional critical details. Full test documentation available upon request.

Test Methodology

  • 19 isolated test files created via bash
  • 9x9 Read×Edit format matrix testing all combinations
  • Fresh files per test to eliminate cross-contamination
  • All tests preserved and reproducible

Key Corrections to Current Issue Description

❌ Correction 1: Both Formats Fail on Cold Cache

Current issue states:

"First edit attempt with forward slashes: ❌ FAILS Same file with backslashes: ✅ WORKS"

Comprehensive testing proves (Tests E1-E2):

  • Edit with C:\path on cold cache: ❌ FAILS ("unexpectedly modified")
  • Edit with C:/path on cold cache: ❌ FAILS ("unexpectedly modified")

Both formats fail equally for cold cache edits on bash-created files. The issue isn't the Edit format - it's whether the cache was properly initialized.


✅ Correction 2: Read Operations Poison Cache (Critical Missing Detail)

The real mechanism:

  1. Read(C:/path/file.txt) succeeds but creates cache entry with key C:/path/file.txt
  2. Edit(C:/path/file.txt) or Edit(C:\path\file.txt) looks for normalized key C:\path\file.txt
  3. Cache miss occurs (C:/fileC:\file in cache key comparison)
  4. Error: "File has been unexpectedly modified"

Test M5 proves this:

  • Read(C:/path/test-m5.txt) ✅ Success
  • Edit(C:/path/test-m5.txt) ❌ FAILS ("unexpectedly modified")
  • Even matching formats fail! The problem is the Read operation, not format mismatch.

Complete Test Matrix Results (Phase 4)

Test Read Format Edit Format Read Result Edit Result Conclusion
M1 C:\ C:\ ✅ Success ✅ Success CORRECT WORKFLOW
M2 C:\ C:/ ✅ Success ✅ Success Formats interchangeable!
M3 C:\ /c/ ✅ Success ❌ "File does not exist" Bash paths not supported
M4 C:/ C:\ ✅ Success ❌ "Unexpectedly modified" Cache poisoned
M5 C:/ C:/ ✅ Success ❌ "Unexpectedly modified" Even same format fails!
M6 C:/ /c/ ✅ Success ❌ "File does not exist" Bash paths not supported
M7-M9 /c/ Any ❌ "File does not exist" ❌ Failed Bash Read not supported

Key Insights

1. Only Backslash Read Creates Valid Cache

  • Read(C:\path\file.txt) is the ONLY safe way to initialize cache
  • Once cache is valid, path formats ARE interchangeable for Edit
  • Read(C:\file)Edit(C:/file) works perfectly (Test M2)

2. Forward Slash Read Poisons Cache for ALL Edits

  • Read(C:/file)Edit(C:/file) fails even with matching formats (Test M5)
  • Read(C:/file)Edit(C:\file) fails with backslash Edit (Test M4)
  • The cache bug affects ALL subsequent Edit attempts, not just cross-format edits

3. Recovery Procedure Validated ✅

Test Rec1 proves recovery is possible:

Step Action Path Result Notes
1 Read (poison) C:/path/test-recovery.txt ✅ Success Cache now poisoned
2 Edit (should fail) C:\path\test-recovery.txt ❌ "Unexpectedly modified" Confirms poisoned
3 Read (fix cache) C:\path\test-recovery.txt ✅ Success Re-reading with backslash
4 Edit (should work) C:\path\test-recovery.txt ✅ Success RECOVERED!

Re-reading with backslash format fixes the poisoned cache entry.


Root Cause Analysis

The Cache Normalization Bug

Why backslash Read works:

Read(C:\path\file.txt) → Creates cache entry: C:\path\file.txt
Edit(any format)       → Normalizes to lookup: C:\path\file.txt
                       → Cache HIT! ✅ Edit succeeds

Why forward slash Read fails:

Read(C:/path/file.txt) → Creates cache entry: C:/path/file.txt
Edit(any format)       → Normalizes to lookup: C:\path\file.txt
                       → Cache MISS! ❌ "Unexpectedly modified"

Fix needed: Normalize paths before storing in cache, not just during lookup.


Recommended Safe Practices

For Read Operations (Critical)

✅ Read(C:\Users\[user]\file.txt)  - SAFE (correct cache)
❌ Read(C:/Users/[user]/file.txt)  - DANGEROUS (poisons cache)
❌ Read(/c/Users/[user]/file.txt)  - FAILS (not supported)

For Edit Operations

After proper backslash Read:

✅ Edit(C:\Users\[user]\file.txt)  - Works
✅ Edit(C:/Users/[user]/file.txt)  - Works (formats interchangeable!)
❌ Edit(/c/Users/[user]/file.txt)  - Never works (not supported)

If Cache Gets Poisoned

  1. Re-read file with backslash format: Read(C:\path\file.txt)
  2. Cache is now fixed
  3. Edit with any Windows path format

Additional Notes

  • Write/Glob/Grep tools: All path formats work (no cache dependencies)
  • Bash-style paths (/c/path): Not supported for Read/Edit (separate issue from cache bug)

Summary

This comprehensive testing:

  1. Confirms the cache poisoning bug exists
  2. Corrects the claim that backslashes work on first Edit attempt (both fail for cold cache)
  3. Identifies Read operations as the source of cache corruption
  4. Proves even matching formats fail after forward-slash Read (Test M5)
  5. Validates recovery procedure by re-reading with backslash paths
  6. Demonstrates path formats are interchangeable once cache is valid (Test M2)

Workaround remains valid: Always use backslash paths for Read operations to ensure correct cache initialization.

full test results are attached

cache-poisoning-bug-comprehensive-testing.md

BenNewman100 avatar Oct 25 '25 00:10 BenNewman100

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.

github-actions[bot] avatar Dec 11 '25 10:12 github-actions[bot]

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.

This is still an ongoing issue where I have to instruct Claude on how to edit files on Windows, otherwise it will be stuck in an edit/fail/read/edit/fail/read loop.

JosiahSiegel avatar Dec 11 '25 16:12 JosiahSiegel