> ## Documentation Index
> Fetch the complete documentation index at: https://tally.wharflab.com/llms.txt
> Use this file to discover all available pages before exploring further.

# tally/powershell/error-action-preference

> Require `$ErrorActionPreference = 'Stop'` and `$PSNativeCommandUseErrorActionPreference = $true` in PowerShell RUN instructions.

Require `$ErrorActionPreference = 'Stop'` and `$PSNativeCommandUseErrorActionPreference = $true` in PowerShell `RUN` instructions.

| Property | Value                      |
| -------- | -------------------------- |
| Severity | Warning                    |
| Category | Correctness                |
| Default  | Enabled                    |
| Auto-fix | Yes (`--fix --fix-unsafe`) |

## Description

This rule detects PowerShell `RUN` instructions that lack fail-fast error handling. It checks for two related preferences:

1. **`$ErrorActionPreference = 'Stop'`** -- catches non-terminating PowerShell cmdlet errors that would otherwise be silently swallowed.
2. **`$PSNativeCommandUseErrorActionPreference = $true`** -- extends error handling to native command exit codes (e.g., `git`, `dotnet`, `curl`) in
   PowerShell 7.3+.

The rule fires on both Linux and Windows stages whenever PowerShell is the effective shell (via `SHELL` instruction or explicit `powershell -Command`
/ `pwsh -Command` wrappers).

## Why this matters

PowerShell does not fail-fast by default. Without `$ErrorActionPreference = 'Stop'`, an intermediate `Invoke-WebRequest` can fail silently, then
`Start-Process` runs on a missing installer, then `Remove-Item` succeeds because nothing was there. The cascading silent failures are the real danger
in multi-statement Docker build steps.

The `$PSNativeCommandUseErrorActionPreference` variable was added in PowerShell 7.3 to close a gap: even with `$ErrorActionPreference = 'Stop'`,
non-zero exit codes from native executables were ignored. Setting it to `$true` extends the fail-fast behavior to all commands.

## Examples

### Before (violation)

```dockerfile theme={null}
FROM mcr.microsoft.com/powershell:ubuntu-22.04
SHELL ["pwsh", "-Command"]
RUN Install-Module PSReadLine -Force; Write-Host "done"
```

### After (fixed with `--fix --fix-unsafe`)

```dockerfile theme={null}
FROM mcr.microsoft.com/powershell:ubuntu-22.04
SHELL ["pwsh", "-Command", "$ErrorActionPreference = 'Stop'; $PSNativeCommandUseErrorActionPreference = $true;"]
RUN Install-Module PSReadLine -Force; Write-Host "done"
```

### Already clean (no violation)

```dockerfile theme={null}
FROM mcr.microsoft.com/powershell:ubuntu-22.04
SHELL ["pwsh", "-Command", "$ErrorActionPreference = 'Stop'; $PSNativeCommandUseErrorActionPreference = $true; $ProgressPreference = 'SilentlyContinue';"]
RUN Install-Module PSReadLine -Force; Write-Host "done"
```

## Configuration

### `min-statements`

Minimum number of PowerShell statements in a `RUN` to trigger the rule.

* **Type:** integer
* **Default:** `2`
* **Minimum:** `1`

Set to `1` to also catch non-terminating error swallowing on single-command `RUN` instructions.

```toml theme={null}
[rules.tally.powershell.error-action-preference]
min-statements = 1
```

## Fix behavior

The auto-fix injects whichever preferences are missing. The strategy depends on the shell context:

* **Existing `SHELL` instruction**: appends the missing preferences to the last argument.
* **No `SHELL` instruction**: inserts a new `SHELL` instruction after the `FROM`.
* **Explicit wrapper** (`RUN powershell -Command ...`): inserts the missing preferences at the
  start of the inner script, right before the first command.

The fix uses `FixSuggestion` safety, requiring `--fix-unsafe` to apply.

## Interaction with other rules

* **`tally/powershell/prefer-shell-instruction`** (priority 95): runs first. If it inserts a SHELL with the full prelude, the error-action-preference
  fix is skipped as overlapping.
* **`tally/prefer-run-heredoc`** (priority 100): when converting multi-statement RUNs to heredocs, the heredoc formatter automatically injects both
  preferences if missing.

## References

* [`$ErrorActionPreference`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables#erroractionpreference)
  \-- Microsoft Learn: controls how PowerShell responds to non-terminating errors. Default is `Continue` (silently
  swallow); `Stop` converts them to terminating errors.
* [`$PSNativeCommandUseErrorActionPreference`](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables#psnativecommanduserroractionpreference)
  \-- Microsoft Learn: when `$true`, non-zero exit codes from native commands are treated as errors according to
  `$ErrorActionPreference`. Added in PowerShell 7.3; default is `$false`.
