gh-fix-ci: inspect_pr_checks.py reports failure snippet from the wrong Actions job

Open 💬 0 comments Opened Jun 19, 2026 by ilganeli

Summary

The github curated Codex plugin's gh-fix-ci skill ships inspect_pr_checks.py, which extracts a CI failure snippet from the wrong Actions job. For a failing check it reads gh run view <run_id> --log — which concatenates every job in the run — and find_failure_index then scans that combined log bottom-up for the last failure marker. So the reported snippet can come from a different job than the failing check.

Concretely: a PR whose Unit Tests check failed produced Integration Tests tail output, requiring a manual log download to find the real pytest failure. This happens whenever a later (passing) job's tail contains a generic marker word (error, fail, timeout, …) that sorts after the truly-failing job's markers in the combined log. The job-scoped log path in the script only runs when the run-level log is still pending.

Affected file

plugins/github/skills/gh-fix-ci/scripts/inspect_pr_checks.py (in openai/plugins; github plugin v0.1.5). Issues are disabled on openai/plugins, so filing here against the Codex plugin set.

The relevant logic is in fetch_check_logfetch_run_log (gh run view --log) → extract_failure_snippet/find_failure_index.

Steps to reproduce

python3 .../skills/gh-fix-ci/scripts/inspect_pr_checks.py --repo . --pr <PR> --max-lines 200 --context 50

on a PR where one check (e.g. Unit Tests) failed and a later job (e.g. Integration Tests) passed but has any failure-marker word in its tail. Observed on two PRs:

  • Run 27505887421, failing Unit Tests job 81296920250 — helper showed Integration Tests output.
  • Run 27505317482, Unit Tests job 81295393027 — same pattern.

Expected

The snippet should be tied to the failing job/check identity. If the failing job's log can't be isolated, the tool should say extraction is uncertain rather than silently showing cross-job output.

Suggested fix (prepared)

I have a fix + regression test ready on a fork (couldn't open a PR to openai/plugins — PR creation is restricted to org members):

Approach:

  1. Prefer the job-scoped log (/repos/{slug}/actions/jobs/{id}/logs) when a job id is present in the check's detailsUrl.
  2. Otherwise isolate the failing job's lines by name within the run log (gh run view --log prefixes each line with <job name>\t<step>\t…) before extracting a snippet.
  3. When neither works, return the run log flagged as ambiguous and say the snippet may span jobs.
  4. Surface the job/check name and the scope used in text and JSON output.

Includes a new test_inspect_pr_checks.py (stdlib unittest, matching the repo's existing script-test convention) with a regression fixture for "Unit Tests failing while Integration Tests has unrelated tail output". All tests pass.

Happy to adjust the approach or output format to whatever you prefer, or hand the patch to a maintainer to land directly.

View original on GitHub ↗