Skip to content
Latchkey

GitHub Actions conditional job skipped but required check stays pending in branch protection

A required status check must report success to merge. A job skipped by an if-condition does not report success - it reports skipped - so branch protection treats the required check as not satisfied and the PR is blocked.

What this error means

A PR is blocked from merging because a required check never reports success; the job was skipped by an if-condition.

github-actions
Required check "build" is expected but the job was skipped.
Merging is blocked: required status check has not reported a successful conclusion.

Diagnose it: print the context before you change anything

Most workflow-expression bugs are not syntax errors, they are an expression reading something that is empty. GitHub resolves a missing property to an empty string instead of failing the run, so a wrong reference looks like a logic bug rather than a mistake. Dump the contexts first and you will usually see the answer immediately.

.github/workflows/ci.yml
- name: Dump contexts
  run: |
    echo '--- github ---'   ; echo '${{ toJSON(github) }}'
    echo '--- needs ---'    ; echo '${{ toJSON(needs) }}'
    echo '--- steps ---'    ; echo '${{ toJSON(steps) }}'
    echo '--- matrix ---'   ; echo '${{ toJSON(matrix) }}'
    echo '--- inputs ---'   ; echo '${{ toJSON(inputs) }}'

Check the context is allowed where you used it

Contexts are not available everywhere. The same expression can be valid in a step if and invalid in a job if, which is why an expression that works in one workflow fails when moved.

Where you wrote itContexts available there
run-namegithub, inputs, vars
concurrencygithub, inputs, vars
Top-level envgithub, secrets, inputs, vars
jobs.<id>.ifgithub, needs, vars, inputs
jobs.<id>.steps.ifgithub, needs, strategy, matrix, job, runner, env, vars, steps, inputs
jobs.<id>.outputsFull access, including secrets
Reusable workflow outputsgithub, jobs, vars, inputs

Common causes

Skipped does not equal success

Branch protection requires a successful conclusion; skipped does not count.

Required check applied to a sometimes-skipped job

Marking a path-filtered job as required blocks PRs that legitimately skip it.

How to fix it

Add a status-reporting fallback job

  1. Create a small always-run job that depends on the conditional one and reports success when it is skipped.
  2. Make that fallback job the required check instead.
.github/workflows/ci.yml
gate:
  needs: build
  if: ${{ always() }}
  runs-on: latchkey-small
  steps:
    - run: |
        if [ "${{ needs.build.result }}" = "failure" ]; then exit 1; fi

Avoid skipping required jobs

  1. Move the conditional logic inside the job so it always runs and exits 0 when there is nothing to do.
  2. Keep the required check able to report success.

Catch it before it reaches CI

Every failure in this cluster is statically detectable. actionlint parses workflow expressions, checks context availability against the same rules above, and validates needs references, so these bugs never need to cost you a run.

Terminal
# one-off
docker run --rm -v "$(pwd):/repo" --workdir /repo rhysd/actionlint:latest -color

# as a job, before anything expensive runs
- uses: actions/checkout@v4
- run: |
    bash <(curl -s https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)
    ./actionlint -color

How to prevent it

  • Do not mark sometimes-skipped jobs as required directly.
  • Use an always() gate job to translate skipped into success.

Frequently asked questions

What causes GitHub Actions conditional job skipped but required check stays pending in branch protection?
There are 2 common causes: skipped does not equal success and required check applied to a sometimes-skipped job. Branch protection requires a successful conclusion; skipped does not count.
How do I fix GitHub Actions conditional job skipped but required check stays pending in branch protection?
There are 2 fixes depending on which cause you have: add a status-reporting fallback job and avoid skipping required jobs. Work through them in order, since the first is the most common.
What does GitHub Actions conditional job skipped but required check stays pending in branch protection actually mean?
A PR is blocked from merging because a required check never reports success; the job was skipped by an if-condition.
How do I stop GitHub Actions conditional job skipped but required check stays pending in branch protection happening again?
Do not mark sometimes-skipped jobs as required directly. The prevention section lists 2 changes that keep it from recurring.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card