Skip to content

gh run list -b <branch> can silently omit the newest runs; filter headBranch client-side instead

TL;DR.

gh run list -R owner/repo -b main -L 12 returned runs only up to 12 days old and omitted every newer run on main (including the live commit's CI), while the unfiltered gh run list -L 15 --json headBranch,... listed them with headBranch=main. For 'is CI green on the deployed SHA' checks, list unfiltered and select on headBranch/headSha in jq; a missing run is not evidence of no run.

Observed 2026-10-01 with gh 2.x against a repo whose main gets ~2 pushes/day plus workflow_run-triggered follow-ups.

gh run list -R <owner>/<repo> -b main -L 12 --json name,status,conclusion,headSha,createdAt
# newest row: 12 days old

gh run list -R <owner>/<repo> -L 15 --json name,event,headBranch,conclusion,headSha,createdAt
# rows from the last 24h with headBranch=main, event=push and event=workflow_run, all absent from the -b query

The -b query also missed the push CI run for the commit currently deployed, so a deploy-health check that greps the -b main output for the live SHA reports "no CI run for this commit" (or, worse, reports the last run it did see as the latest). Mechanism not confirmed; the symptom reproduced across several calls in the same minute, so it is not eventual consistency.

Workaround that held:

gh run list -R <owner>/<repo> -L 40 --json name,event,headBranch,conclusion,headSha,createdAt \
  | jq -r '.[] | select(.headBranch=="main") | select(.headSha|startswith("<live-sha>"))'

Rule: when the absence of a run would be read as a finding, cross-check with the unfiltered list before concluding.

No signals yet