Write tool on Windows produces UTF-8 without BOM for .ps1 files, causing PowerShell 5.1 UnexpectedToken errors
Bug Description
The Write tool in Claude Code writes files as UTF-8 without BOM (Byte Order Mark). On Windows, PowerShell 5.1 interprets files without a BOM as ANSI (Windows-1252). When a .ps1 script contains any non-ASCII characters (emojis, em dash —, arrow →, or umlauts like ä, ö, ü), PowerShell throws UnexpectedToken or ParserError at those positions.
Reproduction Steps
- Use the Claude Code
Writetool to create a.ps1file containing any Unicode character (e.g., emoji✅, em dash—, arrow→, or umlaut) - Run the script with
powershell -NoProfile -File script.ps1on Windows - Result:
ParserError: UnexpectedTokenat the line containing the non-ASCII character
Expected Behavior
.ps1 files written by the Write tool should include a UTF-8 BOM (EF BB BF) so PowerShell 5.1 correctly interprets them as UTF-8.
Actual Behavior
Files are written as UTF-8 without BOM → PowerShell 5.1 reads them as ANSI → Non-ASCII characters cause UnexpectedToken / ParserError.
Environment
- OS: Windows 11 Pro (10.0.22631)
- PowerShell: 5.1 (Windows PowerShell — NOT PowerShell 7/Core)
- Claude Code: CLI version (latest)
Impact
This bug has caused the same failure across 11 separate sessions in my project, each requiring a correction loop that wastes ~500 tokens per occurrence (~5,500 tokens total). The AI has to be re-instructed every session because the Write tool always produces files without BOM and the error only appears at runtime.
Workaround (currently required)
Instead of Write tool for .ps1 files with Unicode content, use node.js:
node -e "const fs = require('fs'); fs.writeFileSync('script.ps1', content, 'utf8');"
Or add BOM manually after writing:
$c = [System.IO.File]::ReadAllText('script.ps1', [System.Text.Encoding]::UTF8)
[System.IO.File]::WriteAllText('script.ps1', $c, (New-Object System.Text.UTF8Encoding($true)))
Suggested Fix
When the Write tool writes a .ps1 file on Windows, prepend the UTF-8 BOM (\xEF\xBB\xBF) to the file content. Alternatively, detect the file extension and encoding context to apply BOM for file types that require it on Windows.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗