Skip to content

poll-pr-checks.sh: contexts(first: 100) has no cursor, so any commit with >100 checks is permanently UNVERIFIED #998

Description

@prql-bot

poll-pr-checks.sh queries statusCheckRollup.contexts(first: 100) with no cursor and bails OVERFLOW → exit 2 when totalCount > 100. On a repo whose full CI matrix registers more than 100 contexts, that makes the script permanently unusable on exactly the PRs it matters most for — and the sessions that hit it improvise a replacement poller in-flight, losing the grouping and self-filtering logic the script exists to provide.

Observed twice on PRQL/prql in the 2026-08-15 Dependabot batch, on both reviews that were gated on CI before approving:

Run PR Head contexts.totalCount Result
31891399008 PRQL/prql#6196 472a1925 116 exit 2 — UNVERIFIED
31891406039 PRQL/prql#6197 0aff65a7 115 exit 2 — UNVERIFIED

The split is systematic rather than incidental: a Dependabot bump touches Cargo.lock, so every path filter opens and the whole matrix (including the nightly release builds) registers — 115–116 contexts. Path-filtered bot PRs in the same window stayed well under the page: PRQL/prql#6199 at 36, PRQL/prql#6198 at 41, PRQL/prql#6194 at 43, PRQL/prql#6193 at 87. So the primitive is available on the PRs a human will look at anyway, and unavailable on the external-dependency bumps tend approves autonomously. The two runs above were the only two gated approvals in that 24h window, and the script refused on both.

No wrong verdict reached the record — both sessions recovered, and PRQL/prql#6196's improvised poller is what caught test-msrv going red four minutes after the approval, which the session then dismissed, diagnosed and fixed. The cost is that each session re-derives a safety-critical primitive under time pressure, and the two derivations were not the same: 31891406039 fell back to gh pr view --json statusCheckRollup, while 31891399008 hand-wrote a GraphQL cursor loop into /tmp/poll6196.sh. Neither inherits the reduction the script's header argues for at length — grouping per (check name, workflow), latest-wins within a settled group, $GITHUB_RUN_ID/$GITHUB_WORKFLOW self-filtering — which is what keeps a concurrency-cancelled sibling from reading as red. On this repo that is not hypothetical: an if: always() omnibus (check-ok-to-merge) sat at FAILURE from a cancelled run for the whole of both sessions.

The guard itself is right — UNVERIFIED beats a false green when a dropped node could hide a failure. The gap is that the query never asks for the next page.

Suggested fix and verification notes

The query already has everything but the cursor. Adding pageInfo { hasNextPage endCursor }, looping with after: while accumulating nodes, then dropping the "OVERFLOW" branch (scripts/poll-pr-checks.sh:91), too_many_contexts() (:131-135), its two call sites (:144, :152) and the exit-2 clause in the header comment (:39-40) removes the failure mode rather than raising the constant. totalCount stops being load-bearing once the loop terminates on hasNextPage.

gh pr view --json statusCheckRollup is not a drop-in substitute, even though it does paginate — I verified it returns all 115 nodes on 0aff65a7 where the single-page GraphQL query reports totalCount: 115, hasNextPage: true. The script deliberately queries by commit OID rather than through the PR (scripts/poll-pr-checks.sh:7-10), and gh pr view follows the current head, which is the exact bug that pinning was added to prevent.

A repo-side workaround (raising the page size, or an overlay note telling sessions to hand-roll) would leave every other consumer with a large matrix in the same place, which is why this is filed here rather than on PRQL/prql.

Reproduce against any commit on this repo:

gh api graphql -f query='
  query($o:String!,$r:String!,$s:String!){
    repository(owner:$o,name:$r){ object(expression:$s){ ... on Commit {
      statusCheckRollup { contexts(first:100){ totalCount pageInfo{hasNextPage} } } } } }
  }' -f o=PRQL -f r=prql -f s=0aff65a743f11a02f061a09e1fd40ad13dc8f487 \
  --jq '.data.repository.object.statusCheckRollup.contexts'
# {"pageInfo":{"hasNextPage":true},"totalCount":115}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions