[BUG] Write tool saves files as UTF-8 without BOM, causing encoding corruption in Windows development tools (Delphi IDE, SSMS)

Resolved 💬 3 comments Opened Feb 24, 2026 by jorgeb77 Closed Feb 28, 2026

Preflight Checklist

  • [x] I have searched existing issues 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

The Write tool in Claude Code saves all generated files (.pas, .dfm, .sql, and others) as UTF-8 without BOM (Byte
Order Mark). On Windows, many development tools default to ANSI/Windows-1252 when no BOM is present, causing silent data corruption of any non-ASCII characters in the generated files.

Environment

  • OS: Windows 11 Pro
  • Shell: bash (Git Bash / MSYS2)
  • Affected tools: Delphi 12 Athens IDE, SQL Server Management Studio (SSMS) 19+
  • Claude Code version: 2.1.51

Steps to Reproduce

Scenario A — Delphi source file (.pas)

  1. Ask Claude Code to create a .pas file containing a Spanish/accented string literal, e.g.:

MessageBox(0, '¿Desea continuar?', 'Confirmación', MB_YESNO);

  1. Claude Code creates the file as UTF-8 without BOM (verifiable with a hex editor: no EF BB BF prefix).
  2. Open the .pas file in Delphi 12 Athens IDE.
  3. Delphi reads the file as ANSI (Windows-1252) because there is no BOM.
  4. Result: The string renders as ¿Desea continuar? / Confirmación at runtime.

Scenario B — SQL script (.sql)

  1. Ask Claude Code to create a .sql file with Unicode string literals:

INSERT INTO TABLE VALUES (N'Día de Año Nuevo');

  1. Claude Code saves the file as UTF-8 without BOM.
  2. Open and execute the script in SSMS.
  3. SSMS reads the file as ANSI; the UTF-8 byte sequences for í (0xC3 0xAD) are interpreted as two Latin-1 characters

(Ã + soft-hyphen).

  1. Result: The database stores DÃa de Año Nuevo — even though the correct N'' Unicode prefix is present.

Scenario C — Delphi form file (.dfm)

  1. Ask Claude Code to create a .dfm file with a caption containing accented characters:

Caption = 'Médicos'

  1. Claude Code saves as UTF-8 without BOM.
  2. Delphi compiles the form reading the DFM as ANSI.
  3. Result: The caption renders as Médicos at runtime.

Root Cause

Files written by the Write tool are encoded as UTF-8 without BOM. On Windows, tools that do not implement encoding auto-detection fall back to the system ANSI code page (Windows-1252 / CP1252). The multi-byte UTF-8 sequences for characters above U+007F are then interpreted as multiple single-byte Latin-1 characters, producing garbled text that is silently written to the file, database, or compiled binary.

Expected Behavior

One of the following:

  1. (Preferred) The Write tool adds a UTF-8 BOM (EF BB BF) to text files on Windows, matching the default behavior of

Delphi 12, Visual Studio, and most Windows-native editors.

  1. The Write tool exposes a parameter to control the output encoding (e.g., encoding: "utf-8-bom" | "utf-16-le" |

"utf-8").

  1. The Write tool detects the file extension and applies the appropriate encoding for well-known formats that expect

BOM on Windows (.pas, .dfm, .dpr, .sql, .cs, .vb, etc.).

Actual Behavior

All files are saved as UTF-8 without BOM regardless of extension, platform, or content.

Impact

  • Silent corruption: No error or warning is shown during file creation.
  • Hard to diagnose: The files look correct when viewed in UTF-8-aware editors (VS Code, Notepad++) but fail in tools

that default to ANSI.

  • Affects Windows developers using any IDE or tool that relies on BOM for encoding detection: Delphi, RAD Studio,

Visual Studio (legacy projects), SQL Server Management Studio, classic Notepad, etc.

Workaround (current)

Use #NNN escape notation for all non-ASCII characters in Delphi string literals (encoding-agnostic):
// Instead of: '¿Desea continuar?'
// Use: #191'Desea continuar?'
For SQL, use NCHAR() function or ensure the file is re-saved as UTF-16 in SSMS before execution.

What Should Happen?

You must save the accented characters correctly.

Error Messages/Logs

Steps to Reproduce

Steps to Reproduce

Prerequisites

  • Windows 10 or Windows 11
  • Claude Code installed
  • A hex editor or the PowerShell command Format-Hex (built into Windows)

---
Reproduce in 3 steps (minimal example)

  1. Ask Claude Code to create a file containing non-ASCII characters:

Use this exact prompt in Claude Code:

Create a file called test_encoding.pas with this exact content:

unit test_encoding;
interface
implementation
procedure Test;
begin
ShowMessage('¿Cómo estás? Día de Año Nuevo');
end;
end.

  1. Inspect the file encoding with PowerShell:

Open PowerShell and run:
# Check the first 4 bytes of the file (BOM detection)
Format-Hex "test_encoding.pas" | Select-Object -First 1

Expected output (UTF-8 with BOM):
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000 EF BB BF 75 6E 69 74 20 74 65 73 74 5F 65 6E 63 unit test_enc
(First 3 bytes must be EF BB BF — the UTF-8 BOM)

Actual output (UTF-8 without BOM):
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000 75 6E 69 74 20 74 65 73 74 5F 65 6E 63 6F 64 69 unit test_encodi
(No BOM — file starts directly with 75 = u)

  1. Verify the corruption in a Windows tool:

Open test_encoding.pas in Notepad (not Notepad++, not VS Code — plain notepad.exe) and observe:

  • Expected: '¿Cómo estás? Día de Año Nuevo'
  • Actual: '¿Cómo estás? DÃa de Año Nuevo'

---
Reproduce the SQL corruption (real-world impact)

  1. Ask Claude Code to create a SQL file:

Create a file called test_unicode.sql with this content:

USE master;
INSERT INTO test_table (nombre) VALUES (N'José García');
INSERT INTO test_table (nombre) VALUES (N'Año Nuevo');

  1. Check encoding:

Format-Hex "test_unicode.sql" | Select-Object -First 1
(Same result: no BOM — first bytes are 55 53 45 = USE)

  1. Open and execute in SSMS:
  • Open the file in SQL Server Management Studio (File → Open → File...)
  • SSMS status bar will show "ANSI" encoding (not UTF-8)
  • Execute the script
  • Query the table: SELECT * FROM test_table
  • Result: José GarcÃa / Año Nuevo stored in the database — data permanently corrupted despite the correct N''

Unicode prefix

Reproduce the Delphi Form file (.dfm) corruption

  1. Ask Claude Code to create a .dfm file:

Create a file called test_form.dfm with this exact content:

object TestForm: TTestForm
Caption = 'Gestión de Médicos'
object Label1: TLabel
Caption = 'Dirección:'
end
object Label2: TLabel
Caption = 'Año de nacimiento:'
end
object Label3: TLabel
Caption = 'Número de cédula:'
end
end

  1. Check encoding:

Format-Hex "test_form.dfm" | Select-Object -First 1
(Result: no BOM — file starts with 6F 62 6A = obj)

  1. Verify the corruption in Notepad:

Open test_form.dfm in plain notepad.exe:

  • Expected: Caption = 'Gestión de Médicos'
  • Actual: Caption = 'Gestión de Médicos'
  1. Real-world impact in Delphi 12:

When Delphi compiles this .dfm reading it as ANSI, the captions render at runtime as:

  • Gestión de Médicos (form title)
  • Dirección: (label)
  • Año de nacimiento: (label)
  • Número de cédula: (label)

---
One-liner verification (no extra tools needed)

# Ask Claude Code to write any file with accented characters, then run:
$bytes = [System.IO.File]::ReadAllBytes("test_encoding.pas")
if ($bytes[0] -eq 0xEF -and $bytes[1] -eq 0xBB -and $bytes[2] -eq 0xBF) {
Write-Host "PASS: UTF-8 with BOM" -ForegroundColor Green
} else {
Write-Host "FAIL: UTF-8 without BOM (first bytes: {0:X2} {1:X2} {2:X2})" -f $bytes[0], $bytes[1], $bytes[2]
-ForegroundColor Red
}

Output: FAIL: UTF-8 without BOM (first bytes: 75 6E 69)

Claude Model

Sonnet (default)

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.51

Platform

Other

Operating System

Windows

Terminal/Shell

PowerShell

Additional Information

_No response_

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗