---
name: gh-run-poll-jobs-not-status
description: "gh run view --json status reads \"queued\" with frozen updatedAt while jobs actually run — poll --json jobs; gh emits \"\" not null so .conclusion // .status renders blank."
metadata: 
  node_type: memory
  type: feedback
  originSessionId: d780a4d4-c7b1-44a2-818b-9d5f41a0eb4e
  modified: 2026-08-02T17:07:31.277Z
---

`gh run view <id> --json status` returned `queued` with `updatedAt` frozen while both `test` jobs were `in_progress` (run 30509109149, 2026-07-30). doyle nearly opened a false "runner deaf" incident off it. Also: gh emits `""` not `null` for pending conclusions, so `.conclusion // .status` jq renders blank.

**Why:** the run-level status field lags/lies under queued n1-gate jobs; job-level state is the truth.

**How to apply:** poll `gh run view <id> --json jobs`, never `--json status`. When gating on completion, require every job `completed success` and expected jobs PRESENT by name (not skipped, not absent). See [[v0460-published]].

**Reading a red while the run is still going (2026-08-02, golden 30754060525):** `gh run view --log-failed` REFUSES with "run is still in progress; logs will be available when it is complete" — but `gh api repos/<o>/<r>/actions/jobs/<job_id>/logs` serves a COMPLETED job's log immediately, and job ids come from the same `--json jobs` call. A run still running is not a run you cannot read.

**Two traps in the log itself:** grepping for `FAIL|error` matches TEST NAMES containing "failed" (`failedaddr::tests::…`, `stage_then_swap_failed_fetch_preserves_install`) and reports carnage while every suite is green — read the `##[group]Run` step boundaries and the `##[error]` line to find which STEP died. A `test` job can red with 2584/2584 passing because the failure is a later step (clippy, or a link step that cannot replace `target\debug\spt.exe`). See [[live-agents-lock-target-debug-spt-exe]].
