T09
A .cmd / .bat file runs its comment text as commands
Symptom
Parts of rem comments come back as "is not recognized as an internal or external command", or lines are skipped. Changing the encoding does not fix it.
Check it in 30 seconds
Paste into Windows PowerShell 5.1. It only creates files under your %TEMP% folder. If the last line says REPRODUCED, it happens on your machine.
$d = Join-Path $env:TEMP ('cc-trap-' + (Get-Date -Format 'yyyyMMddHHmmss')); New-Item -ItemType Directory $d -Force | Out-Null
$k = [string][char]0x65E5 + [char]0x672C
[IO.File]::WriteAllText("$d\lf.cmd", "@echo off`nrem $k$k$k comment`nrem $k more`necho START`necho END`n", [Text.Encoding]::GetEncoding(932))
$o = cmd /c "`"$d\lf.cmd`" 2>&1" | Out-String; $e = $LASTEXITCODE
$extra = @($o -split "`r?`n" | Where-Object { $_.Trim() -ne '' -and $_.Trim() -ne 'START' -and $_.Trim() -ne 'END' })
$o; "console code page $([Console]::OutputEncoding.CodePage), exit=$e, unexpected lines=$($extra.Count)"
if ($e -ne 0 -or $o -notmatch 'START' -or $extra.Count -gt 0) { 'REPRODUCED' } else { 'NOT REPRODUCED' }
Why it happens
The real cause is the line endings. cmd.exe can misread line boundaries in an LF-only batch file. On the author's machine it broke under code page 932 (Japanese), not under 65001, 437 or 1252, so on English Windows this check may say NOT REPRODUCED.
Fix
Save .cmd / .bat files with CRLF line endings. In git, add *.cmd text eol=crlf to .gitattributes.
$enc = [Text.Encoding]::GetEncoding(28591) # one byte per char: the file's bytes stay as they are
$t = [IO.File]::ReadAllText($path, $enc)
$t = ($t -replace "`r`n", "`n") -replace "`n", "`r`n"
[IO.File]::WriteAllText($path, $t, $enc)
On the author's machine
broke under cp932, ran fine under cp65001
Author's machine: Windows 11 / Windows PowerShell 5.1.26100 / Python 3.13.7 / Claude Code 2.1.304, Japanese Windows (code page 932). Checked 2026-10-20 to 22.
If you searched for
Related
cc-win-kit bundles the parts that avoid these traps from the start: a write guard (with onFailure: block), an unattended runner, a doctor that scans your files and hook settings, CLAUDE.md templates and the full test suite.
Other symptoms
- PowerShell returns exit code 1 when the script exited with 2
- The second value passed with -File disappears without an error
- With -File, a,b stays one string instead of an array
- Non-ASCII text piped to claude -p, python or git arrives as ?
- Output from python or claude turns into mojibake in a variable
- Python works when run by hand but crashes under Task Scheduler or redirection
- PYTHONIOENCODING is set, but python -I ignores it
- A .ps1 with non-ASCII text fails to parse or prints mojibake
- $variables in a powershell -Command one-liner vanish before it runs
- Get-ChildItem -Include is ignored and every file comes back
- Markdown backticks inside "..." turn into newlines and tabs
- A log that is being written shows 0 bytes
- claude -p --allowedTools swallows the prompt after it
- A Claude Code PreToolUse hook lets the write through when it times out
- A PowerShell hook called with -Command does not block Claude Code
- No Claude Code hook runs at all (disableAllHooks is still set)