Why Your GitHub PR Checks Get Stuck Forever and The Fix
- Get link
- X
- Other Apps
Why Your GitHub PR Checks Get Stuck Forever and The Fix
TL;DR
If you open a pull request against one branch (for example, develop) and later retarget it to another branch that has GitHub rulesets requiring specific workflows (for example, main), the newly required checks can become stuck showing:
Expected — Waiting for workflow to run
Not queued. Not in progress. Just permanently stuck, with no workflow run ever created for that check.
The fix is simple: push a new commit (even an empty commit). However, understanding why this happens can save a lot of debugging time.
The Setup
We use an organization-level GitHub ruleset to enforce that certain workflows must run and pass before a PR can be merged into protected branches.
Example:
The reusable workflow itself looks like:
This is a common "golden path" pattern:
- Workflows live in a central repository.
- Application repositories consume them through reusable workflows.
- Rulesets make them mandatory for protected branches.
This keeps CI/CD governance centralized and consistent.
What Happened
Step 1
A PR was opened against develop.
Since develop was not covered by the ruleset, no required workflow checks were enforced.
Step 2
A few minutes later, the PR was retargeted to main using GitHub's Edit → Change Base Branch functionality (or via the Pull Request API).
Step 3
GitHub immediately recognized that main is protected by the ruleset and added the required checks:
- 🏗 Build → Expected
- 🛡 Security Scan → Expected
Step 4
Nothing happened.
The checks remained in the following state indefinitely:
Expected — Waiting for workflow to run
No jobs appeared in the Actions tab.
No workflow execution started.
No progress was ever made.
Diagnosing the Problem
The GitHub UI is misleading in this scenario.
"Waiting for workflow to run" sounds like something is queued and will eventually execute.
In reality, nothing is scheduled.
We confirmed this using the GitHub API:
Output:
No check-runs existed.
Checking check suites produced the same result:
Only unrelated suites appeared. No suites existed for the required ruleset workflows.
Things We Ruled Out
We systematically eliminated the usual causes:
- ❌ GitHub outage or incident
- ❌ Missing or broken workflow tag reference (
refs/tags/v1) - ❌ Invalid workflow YAML
- ❌ Missing repository custom properties
- ❌ Actions disabled
- ❌ Permission issues
Everything looked healthy.
The Clue
The breakthrough came from inspecting the PR timeline via GraphQL:
Result:
The PR's base branch had changed several minutes after creation.
Root Cause
GitHub Actions workflows triggered by pull_request events only run for specific PR lifecycle events, such as:
openedsynchronizereopenedready_for_review
A base branch change is not one of those events.
This creates a split-brain situation between two GitHub subsystems.
Ruleset Engine
When the base branch changes:
the ruleset engine immediately re-evaluates branch protection requirements.
It determines:
This PR now requires Container Build and SAL Scan.
The checks are added to the merge requirements instantly.
Actions Dispatcher
However, GitHub Actions does not dispatch a new pull_request event when the base branch changes.
Therefore:
- No workflow run is created.
- No checks start.
- No check-runs exist.
- No check-suites exist.
The required checks now exist only as expectations.
Nothing is available to satisfy them.
The PR becomes stuck in a state that cannot resolve itself.
The Fix
The solution is to trigger a new PR event.
The easiest method is an empty commit:
This generates a:
event.
GitHub Actions then dispatches the required workflows, and the checks begin running normally.
Alternative
Closing and reopening the PR also works because GitHub fires a fresh PR lifecycle event.
However, this is generally less desirable because it can affect review workflows, notifications, and UI state.
An empty commit is usually the cleanest option.
Key Takeaways
1. "Expected" Does Not Mean "Queued"
If a check shows:
Expected — Waiting for workflow to run
for more than a few minutes, verify that an actual workflow run exists.
Check:
and
If neither contains the required workflow, waiting longer will not help.
2. Base Branch Changes Do Not Retrigger Workflows
Changing:
updates branch protection and rulesets immediately, but does not trigger pull_request workflows.
Always assume a follow-up push is required after retargeting an existing PR.
3. Rulesets + Reusable Workflows Have This Edge Case
Organizations that use:
- Centralized reusable workflows (
workflow_call) - Organization-level rulesets
- Protected branches
are particularly likely to encounter this behavior.
Common scenarios include:
- Switching a PR from
developtomain - Branch strategy changes
- Renamed default branches
- Deleted or replaced release branches
The ruleset updates immediately, but Actions remains unaware until another PR event occurs.
Final Recommendation
Whenever a PR's base branch is changed to a branch with different required checks:
Treat this as standard practice.
It immediately forces GitHub Actions to re-evaluate the PR, run the newly required workflows, and satisfy the updated ruleset requirements.
❤️ Support This Blog
If this post helped you, you can support my writing with a small donation. Thank you for reading.
- Get link
- X
- Other Apps
Comments
Post a Comment