How to Fix a GitHub Actions Workflow That Is Failing
A GitHub Actions workflow can fail silently in three distinct ways: a YAML syntax error that prevents it from parsing at all, a step order bug where checkout runs after the code is needed, and an unpinned action reference that breaks reproducibility. Here's how to diagnose and fix all three.
Why workflows fail before they even run
GitHub Actions validates workflow YAML before executing any steps. A single
indentation mistake - even one character off - produces a parse error and the
job never starts. Use actionlint locally to catch these instantly instead of
waiting for a remote push-and-fail cycle:
actionlint .github/workflows/ci.yaml
actionlint prints the exact file, line, and column of every problem. A
common output looks like:
.github/workflows/ci.yaml:14:5: mapping values are not allowed in this context [yaml-syntax]
That pinpoints a bad indent - fix the whitespace, re-run, repeat until the linter exits 0.
The step order trap
Even after the YAML is valid, jobs can fail because steps run in the order
they appear in the file. actions/checkout must come first - before any
step that reads the repo's code. A workflow like this fails silently:
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Run unit tests # runs against an EMPTY directory
run: python3 -m unittest discover -s tests -t .
- name: Checkout # too late - code isn't here yet
uses: actions/checkout@v4
The test step runs against an empty runner workspace, finds no tests, and may exit 0 or fail with a confusing "no tests found" error. Swap the order: checkout always goes first.
Pin actions to a tag, never a branch
actions/checkout@main is not reproducible. The main branch of an action
repository can change any time, meaning your CI can break or silently change
behavior on any push even when your own code is untouched. Pin to a major
version tag or a full commit SHA:
- uses: actions/checkout@v4 # pinned to major tag
# or for supply-chain security:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # SHA pin
The fixed workflow
After applying all three fixes - correcting the YAML indent, moving checkout
first, and pinning to @v4 - the file looks like:
name: CI
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Run unit tests
run: python3 -m unittest discover -s tests -t .
Validate locally before pushing with act, which runs the workflow on your
machine without a GitHub round-trip:
act push -j test
A green act run means the job will pass on GitHub too.
Best practices going forward
- Add
actionlintas a pre-commit hook so YAML errors never reach the repo. - Use Renovate or Dependabot to keep action versions current automatically.
- Pin third-party actions to a commit SHA in security-sensitive pipelines.
Want to try it hands-on? HeyDevJob gives you this exact setup in a live cloud workspace in your browser - edit it, run it, and see it work. Free, nothing to install.
Try it in a workspace →What you'll practice
- Running actionlint to find YAML syntax errors and wrong step references
- Ordering steps correctly so actions/checkout runs before any code-dependent step
- Pinning actions to a version tag or SHA for reproducible CI
FAQ
Why is my GitHub Actions workflow failing with a YAML syntax error?
A single indentation mistake stops GitHub Actions from parsing the workflow at all. Run actionlint .github/workflows/ci.yaml locally - it shows the exact line and column of the problem so you can fix it without a push-and-fail cycle.
Why does my GitHub Actions job run but find no code in the workspace?
The actions/checkout step is probably listed after the step that needs the code. Steps run top to bottom, so checkout must come first - before any step that reads, builds, or tests the repo.
Should I pin GitHub Actions to a branch like @main?
No - pin to a version tag like @v4 or a full commit SHA. A branch reference like @main can change any time the action maintainer pushes, silently breaking or altering your CI without any change to your own code.
Keep learning
Learn it by doing. Open this in a live cloud workspace, make the change yourself, and keep a record of the work you can share.
Open the workspace →