All symptoms日本語

T01

PowerShell returns exit code 1 when the script exited with 2

Symptom

The script exits with code 2, but the caller sees 1. Codes 0 and 1 come through unchanged, so only a scheme like "2 = skipped, 1 = failed" breaks, and it breaks silently.

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
[IO.File]::WriteAllText("$d\exit2.ps1", 'exit 2')
powershell -NoProfile -ExecutionPolicy Bypass -File "$d\exit2.ps1"; $a = $LASTEXITCODE
powershell -NoProfile -ExecutionPolicy Bypass -Command "& '$d\exit2.ps1'"; $b = $LASTEXITCODE
"-File=$a  -Command=$b"
if ($a -eq 2 -and $b -eq 1) { 'REPRODUCED' } else { 'NOT REPRODUCED' }

Why it happens

When you call powershell -Command "& 'x.ps1'", PowerShell returns whether the last command succeeded (0 or 1), not the script's exit code. With -File the script's exit code is returned as is.

Fix

Call scripts with -File. If you must use -Command, end it with ; exit $LASTEXITCODE.

powershell -NoProfile -ExecutionPolicy Bypass -File .\x.ps1
powershell -NoProfile -Command "& '.\x.ps1'; exit $LASTEXITCODE"

On the author's machine

-File=2 -Command=1

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.

cc-win-kit ($19 on Payhip)

Other symptoms