Fix "Waiting for status to be reported" on GitHub
Updated
A pull request shows Expected — Waiting for status to be reported when a required check hasn't reported on its latest commit. Usually the check's workflow never started, so GitHub waits for a result that won't come, and the pull request can't merge.
Find the cause
| Cause | How to recognize it | Fix |
|---|---|---|
A paths, paths- or branches filter skipped the workflow | The workflow has a filter, and this pull request's files or branch fall outside it | Move the filter into the job |
[skip ci] in the commit message | The latest commit's message contains it | Push a commit without it |
| The job's name changed | The required name matches no job, as after a rename | Update the name in the branch's rule |
| A matrix | Each combination reports its own check, such as test (20), not test | Require one summary job |
| A merge queue | The check passed on the pull request, and waits in the queue | Add the merge_ trigger |
GitHub's troubleshooting page puts the rule this way: avoid requiring workflows that can be skipped.
Move the filter into the job
A paths filter on the workflow stops it from starting, so nothing reports. A job skipped by if: is different: GitHub reports it as a success. Start the workflow every time and decide in the job:
on:
pull_request:
jobs:
changes:
runs-on: ubuntu-latest
permissions:
pull-requests: read
outputs:
code: ${{ steps.filter.outputs.code }}
steps:
- uses: dorny/paths-filter@v4
id: filter
with:
filters: |
code:
- "src/**"
- "package-lock.json"
test:
needs: changes
if: needs.changes.outputs.code == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- run: npm ci
- run: npm testOn a pull request that changes only documentation, test is skipped and reports success, so the pull request can merge.
There's a trap here. A job whose dependency fails is skipped too, and GitHub says that skip may not block merging. If changes fails, test can look fine with nothing tested. A summary job closes that gap.
Require one summary job
Add a job that always runs and fails when any other job failed, and make it the only required check:
ci-ok:
needs: [changes, test]
if: always()
runs-on: ubuntu-latest
steps:
- if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
run: exit 1if: always()is what makes this safe. Without it,ci-okis skipped when a job it needs fails, and a skipped check may let the pull request through.- Skipped jobs don't fail it, so a filtered job doesn't block a merge.
- The required list stays one name, whatever you add to the matrix or rename.
Report in the merge queue
Checks in a merge queue report on a temporary merge commit, and pull_request doesn't start a workflow there. A workflow that's required in the queue needs the merge_group trigger too:
on:
pull_request:
merge_group:In the queue, dorny/paths-filter reads the changes with git, not GitHub's API. The changes job above then needs a checkout, and the permission for it:
changes:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
outputs:
code: ${{ steps.filter.outputs.code }}
steps:
- uses: actions/checkout@v7
- uses: dorny/paths-filter@v4
id: filter
with:
filters: |
code:
- "src/**"
- "package-lock.json"Don't remove the requirement
Taking the check off the required list unblocks the pull request, and every later one, with nothing tested. If you need to merge past it once, and your rule allows bypassing, an admin can do that for one pull request and leave the rule in place.
With hushrun
A path filter asks what changed. hushrun run asks whether this exact code already passed, so the workflow can start every time with no filter to keep up to date:
jobs:
test:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 22
- run: npm ci
- run: npm testHere npm test is wrapped once in package.json, as hushrun run -- vitest run. A skip exits 0, so the required check always reports. A change anywhere in the repository runs the check again, unless you narrow it with scopes. The job still starts and installs, so hushrun saves the check's minutes, not the job's. In CI has the setup.