GH

GitHub Actions Error Handling

Step failure strategies, conditional execution, and retry patterns in GitHub Actions workflows

Details

Language / Topic
github-actionsGitHub Actions
Category
Error Handling

Rules

balanced
- Use `if: failure()` to run cleanup or notification steps only when a preceding step fails: `if: failure() && steps.deploy.outcome == 'failure'`.
- Set `continue-on-error: true` on non-critical steps (e.g. linters) so a failure doesn't block the entire job.
- Use `timeout-minutes` on jobs and steps to prevent hung runners from consuming minutes indefinitely.
- Retry flaky network steps with the `nick-fields/retry` action or a shell loop: `for i in 1 2 3; do curl ... && break || sleep 5; done`.
- Control step execution with outcome conditions: `if: steps.tests.outcome == 'failure'` runs a step only when a named step failed; `if: always()` runs regardless of previous failures — use `always()` for cleanup steps that must run even on job failure.
- Set `continue-on-error: true` on optional/informational steps so a failure reports a warning without blocking the workflow — do NOT use it on critical steps like tests or deployments.
- Use `timeout-minutes` at both the job and step level: `timeout-minutes: 10` on a job prevents stuck runners consuming CI minutes indefinitely.
- Set `fail-fast: false` in matrix strategies when you want all matrix combinations to run regardless of individual failures: `strategy: { fail-fast: false, matrix: { os: [ubuntu, macos] } }`.
- Use `::error::` workflow commands to surface structured errors in the GitHub UI: `echo '::error file=src/main.ts,line=10::Null pointer dereference'`.
- Add `on.workflow_run` triggers to run notification/rollback workflows when a deployment workflow fails.