[BUG] Claude Code does not respect file encoding, corrupts Windows-1252 files
Open 💬 23 comments Opened Sep 4, 2025 by edlyra
Environment
- Platform (select one):
- [ X] Anthropic API
- [ ] AWS Bedrock
- [ ] Google Vertex AI
- [ ] Other: <!-- specify -->
- Claude CLI version: 1.0.103 (Claude Code)
- Operating System: Windows 11
- Terminal: VSCode
Bug Description
Claude Code does not respect the original file encoding when editing files. It assumes UTF-8 encoding for all operations, which causes character corruption when working with files encoded in other formats like Windows-1252.
Steps to Reproduce
- Open a file that is encoded in Windows-1252 (common for Delphi/Pascal projects)
- Use Claude Code's Edit tool to modify text containing accented characters (e.g., Portuguese: configuração, não)
- The file becomes corrupted with characters like configuração instead of configuração
Expected Behavior
Claude Code should:
- Detect the original file encoding
- Preserve the same encoding when making edits
- Or provide a way to configure the target encoding for edits
Current Workaround
Users must either:
- Accept corrupted characters and manually fix them
- Maintain separate UTF-8 clones of their repositories specifically for Claude Code usage
- Use pre-commit scripts to convert between encodings
Impact
This affects any codebase that uses non-UTF-8 encoding, particularly:
- Legacy Delphi/Pascal projects (Windows-1252)
- Projects with specific encoding requirements
- International projects with accented characters
Technical Details
- Claude Code's Read tool correctly displays Windows-1252 files
- The Edit/Write tools force UTF-8 output regardless of input encoding
- VSCode correctly shows Windows-1252 files when configured properly
- The issue only occurs when Claude Code modifies the files
Environment
- Claude Code version: [current version]
- File encoding: Windows-1252 (ANSI - Latin 1)
- IDE: Delphi XE
- Language: Portuguese (Brazilian) with accented characters
This is a critical issue for maintaining legacy codebases that require specific encodings for compiler compatibility.
23 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
Please give your issue a descriptive title
fixing the errors generated by this issue consumes a lot of tokens
2 workarounds are on this older ticket : https://github.com/anthropics/claude-code/issues/3416
The best is probably to use this : https://github.com/devslimbr/cc-tools
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.
Still an issue. Same with Win-1251 encoding
Still actively affecting users. This issue is part of a larger UTF-8/encoding bug pattern in Claude Code's Edit/Write tools.
I've posted a consolidated impact analysis at #13939 documenting 6+ related issues spanning 6+ months. This is a systemic problem affecting all international users.
Cross-linking for visibility: #13939, #13080, #7332, #7335
---
🤖 Generated with Claude Code
If anyone needs a workaround today I wrote an MCP server that handles encoding-aware file reads and writes CP1251, CP1252, ISO-8859, KOI8 with auto-detection. Single Go binary, no runtime dependencies.
https://github.com/dimitar-grigorov/mcp-file-tools
Still an issue, changing from windows-1252 to UTF-8 even when explicitly told not to do so.
How come this is still a problem? Correct file encoding handling is a basic feature. Has there been any official comment from Anthropic on this besides this comment: https://github.com/anthropics/claude-code/issues/13939#issuecomment-3863005735
This is also affecting me in my VBA work with Spanish, as well as in Quechua languages. I'm using Claude through VSC. Every time it touches my code, the whole file comes back garbled.
The problem remains, I'm facing changing from windows-1252 to UTF-8.
Just adding here another "me too"
Facing the same problem, would be nice to have native solution.
I'm adding my share to raise the issue with developers supporting legacy code in C++ Builder 6.
I think we all agree that both the encoding and the line endings should just be preserved as-is.
Why a hook : hooks intercept the native Read/Edit/Write, so Claude doesn't need to remember to use a special tool. The file just stops getting corrupted, transparently.
Design goal : keep the file as-is.
chardetdetects — they should work. Reports welcome.binaryornotpre-check so binary files aren't misidentified as text.If you need read/write encoding mapping rather than strict round-trip (e.g. read GB2312 → write GBK, or ISO-8859-1 → Windows-1252), feel free to open an issue and I'll look into it.
Install:
/plugin marketplace add ymonster/claude_encoding_guard
/plugin install encoding-guard
Repo: https://github.com/ymonster/claude_encoding_guard
Been using @ymonster's
encoding-guardplugin and it solves this cleanly, hooks intercept Read/Edit/Write, chardet detects the original encoding, and the file is round-tripped back to its original encoding + line endings transparently. No more mojibake on Windows-1252 / ISO-8859-1 files.https://github.com/ymonster/claude_encoding_guard
Until Anthropic ships a native fix, this is the most reliable workaround I've found.
Claude says:
Still reproduces on current Claude Code (CLI as of mid-2026) on Windows 11.
Worth flagging that on Windows this is really two stacked bugs that compound:
old_stringcontaining→(U+2192),—(U+2014),’(U+2019),“/”(U+201C/U+201D) or U+00A0 gets normalized/conflated before matching, so the edit either fails with "String to replace not found in file." or silently swaps the glyph. Tracked separately in #15920, #38765, #52813, #26141 — all currently closed as not-planned / stale.On a cp1252 Windows file that also contains an em dash you hit both at once: the matcher can't locate the line, and when it does, the write corrupts the rest of the file's accented bytes.
Minimal repro for the normalization half (reproduces on any OS):
a — b(the—is U+2014)old_string: "a — b"String to replace not found in file. (note: Edit also tried swapping \uXXXX escapes and their characters; neither form matched, so the mismatch is likely elsewhere in old_string.)A single fix would resolve the whole cluster: treat
old_stringas an opaque byte sequence for matching, and preserve the file's detected encoding on write (or expose an--encodingoverride /preserveUnicodeopt-out, applying any "helpful" normalization only as a fallback after a literal match fails, and surfacing which form matched).Until then the only reliable workaround is shelling out to Python with an explicit
encoding=and feeding the codepoints as ASCII\uXXXXescapes so the corrupting path is bypassed entirely.Facing the same problem, would be nice to have native solution.
AI nowadays could do anything, but they can't solve this single issue.
Facing the same problem, would be nice to have native solution.
Adding another data point:
Environment: Claude Code via AWS Bedrock
Codebase: Legacy PL/I mainframe sources stored in Latin-1 / ISO-8859-1 (not UTF-8). The encoding is mandated by the toolchain and can't be changed.
Symptoms (same mechanism described above):
git diffwith false encoding noise, and the result is invalid for a toolchain that requires Latin-1.Current workaround — bypassing Read/Edit with a Python shim
Confirming this on a legacy Delphi (Windows-1252/ANSI) codebase, with a minimal, deterministic reproduction that isolates the tool from any editor.
Key finding: an ASCII-only edit — a change that touches no non-ASCII characters — still corrupts every non-ASCII byte in the whole file. So this isn't about the edited span; the tool round-trips the entire file through a lossy UTF-8 decode/encode.
Minimal reproduction
``
powershellr$enc = [System.Text.Encoding]::GetEncoding(1252)
$ae=[char]0xE4;$oe=[char]0xF6;$ue=[char]0xFC;$ss=[char]0xDF;$Ae=[char]0xC4;$Oe=[char]0xD6;$Ue=[char]0xDC
$txt = "line 1: ASCII marker MARKER_A
n// umlauts: $ae $oe $ue $ss $Ae $Oe $Uernline 3: ASCII endrn"
``[System.IO.File]::WriteAllText("repro.txt", $txt, $enc)
# -> 7 valid cp1252 bytes (E4 F6 FC DF C4 D6 DC), 0x EF BF BD sequences, 80 bytes
repro.txt. It displays the 7 umlauts as the replacement character�(U+FFFD) — i.e. the original bytes are already lost at read time.MARKER_A→MARKER_B(line 2 is untouched).``
powershell
``$b=[System.IO.File]::ReadAllBytes("repro.txt")
($b | Where-Object { $_ -in 0xE4,0xF6,0xFC,0xC4,0xD6,0xDC,0xDF }).Count # valid cp1252 umlauts
$c=0; for($i=0;$i -lt $b.Length-2;$i++){ if($b[$i]-eq0xEF -and $b[$i+1]-eq0xBF -and $b[$i+2]-eq0xBD){$c++} }; $c # EF BF BD sequences
Result
| | valid cp1252 umlaut bytes |
EF BF BDsequences | size ||---|---|---|---|
| before edit | 7 | 0 | 80 |
| after ASCII-only edit | 0 | 7 | 94 |
Every umlaut (
E4,F6, …) becameEF BF BD(the 3-byte UTF-8 encoding of U+FFFD), and the file grew by 14 bytes (7 × 2). In a Windows-1252 editor these now show as�.Why this is bad
Note re: editors
The Zed editor itself recently added legacy-encoding open/save with auto-detection (zed-industries/zed PR #44819, merged 2025-12), and it preserves Windows-1252 on save. But the agent Edit/Write tools still corrupt the file (reproduced above), which suggests they write directly rather than through the encoding-aware path.
Suggested fix
Detect the file's encoding on read and preserve it on write; or, at minimum, don't re-encode bytes that weren't part of the edit. A per-file/target-encoding override would also work.
Environment
Pro 22H2)Claude Code (CLI) 2.1.193, accessed viaZed 1.10.0