Skip to content

A handled $LASTEXITCODE still fails your CI step

exit codes · case

7.xmisleading-errorcifirst-partyrepro: verifiedexit-code-propagation
Affectspwsh 7, actions runner
Fails asEXIT CODE LEAK
Mechanismexit code propagation
Safe fixexplicit exit zero

A shell: pwsh GitHub Actions step runs a native command whose non-zero exit is EXPECTED (e.g. schtasks /query returning 1 because the task was already deleted — which is success for an uninstall check). The script handles the code correctly, prints the right message… and the step still fails red.

- shell: pwsh
run: |
schtasks /query /tn "gone-task" 2>$null
if ($LASTEXITCODE -ne 0) { Write-Host "task removed - OK" }
# step exits 1 anyway: the last native exit code leaks into the step result

The pwsh process exit code defaults to the LAST native command’s exit code when the script ends without an explicit exit. Actions’ shell: pwsh wrapper surfaces that as step failure — even though your logic already consumed and handled the value. This is distinct from exit-code-vs-dollar-q ($? lying): here you READ $LASTEXITCODE correctly and it still leaks.

  • End the script (or the expected-failure branch) with an explicit exit 0.
  • Treat every shell: pwsh step whose last statement is a native command as suspect; make the final exit explicit.