← Required Checks Drift Check

How a required status check goes stale, and how to fix it

Branch protection's "Require status checks to pass" list is a list of names. GitHub never re-derives it from your workflow files — it just waits for something to report a status under each name. Three ordinary changes leave a name nothing will ever satisfy again:

1. The job was renamed

jobs:
  build:            # was required as "build"
    name: Build and Test   # now reports as "Build and Test" instead

Adding a name: to a job that previously had none — or changing an existing one — changes the check-run name GitHub reports. Branch protection still has the old name. Every new pull request now waits on a status that will never arrive.

2. The job was removed or its id changed

Deleting a job outright, or renaming its job id when it has no name: override, is the same failure by a different route: the name branch protection requires simply stops being produced.

3. The workflow dropped its pull_request trigger

on:
  push:            # used to also list pull_request
    branches: [main]

GitHub can only post a status onto a pull request from a run that pull request triggered. A workflow that only runs on: push can have a job with exactly the right name and still never satisfy a required check on a PR — this looks identical to a rename from the branch-protection screen, but the fix is different: restore the trigger, don't rename anything.

Fixing it

Either remove the stale name from Settings → Branches → Branch protection rules, or make a current job report under that exact name again (an explicit name: override is the least disruptive way, since it doesn't require touching the job id or its steps).

Paste your required checks and workflow YAML into Required Checks Drift Check to find every stale or no-pull-request-trigger name across every workflow file at once, or run the CLI in your own repository:

gh api repos/:owner/:repo/branches/:branch/protection > protection.json
python3 check.py --required-checks protection.json --fail-on-stale

That exits with a nonzero status if any required check is stale — wire it into your own CI, or run it once after any branch-protection or workflow change.