CI monitoring widget shows "CI checks unavailable, check gh installed" despite gh being installed/authenticated and PR checks passing
Status Open
Maintainer reply None cached
Activity 4 comments · opened Jul 16, 2026
Description
The CI monitoring feature (the popover shown when clicking the CI status chip on a PR reference in the session) reports:
CI checks unavailable Check that gh is installed and authenticated.
This is incorrect — gh is installed, authenticated, and working, and the PR's checks are all passing on GitHub itself.
Environment
- macOS (Apple Silicon)
gh version 2.96.0, installed via Homebrew at/opt/homebrew/bin/ghgh auth statussucceeds (logged in via keyring)- Confirmed via
gh pr checks <PR>from a terminal that all checks pass (GitHub Actions, Bitrise, CodeQL, CodeRabbit, DevBot Linter) - Confirmed via the GitHub web UI (
.../pull/<PR>/checks) that all checks are green
Troubleshooting already done
- Restarted the Claude Code app — no change
- Verified
ghresolves under a barelaunchd-stylePATH(/usr/local/bin:/bin:/usr/bin) by symlinkingghinto/usr/local/bin— no change - Verified
gh auth statussucceeds whenHOMEis set (ruling out a stripped-environment auth issue) — no change
None of these environment-level fixes resolved the widget, suggesting the "check gh is installed" message is either a generic/misleading fallback, or the underlying check isn't actually shelling out to the user's local gh the way it's described.
Expected behavior
The CI monitoring widget should reflect the actual (passing) CI status shown on GitHub, or at minimum surface a more specific error than a generic "check gh is installed" message when gh is demonstrably installed and working.
4 Comments
+1
+1
Deep-dive from another affected machine: I instrumented the app from outside and verified every layer individually healthy — including capturing the app's own
ghspawn succeeding — yet the widget still reports unavailable. Evidence points at the renderer layer, plus a plausible trigger matching #59182 (session cwd is not a git repo).Environment: Claude desktop 1.24012.9 (bundled CLI 2.1.219), macOS 26.5 (Intel), gh 2.92.0 at
/usr/local/bin/gh, keyring auth. PRs on a private org repo;gh pr checksfrom a terminal shows all checks green.What I verified:
ghsuccessfully. I placed a transparent logging shim as the firstghon PATH. On app launch, the main process spawnedgh auth token --hostname github.com(envAI_AGENT=claude-desktop_1-24012-9_harness, cwd=$HOME) — exit 0, 41-byte token on stdout, empty stderr. So PATH resolution, spawning, and keychain access all work. (Current builds also carry/usr/local/binand/opt/homebrew/binas hardcoded fallback search paths, so the stripped-launchd-PATH theory from the OP can't be the cause on 1.24012.x.)api.github.comreturns a proper 401 JSON when loaded from the in-app browser pane. The REST timeout in the bundle is 15s; observed latency ~0.5s.LocalSessions.checkGhAvailable: cwd=...is logged once per app launch (at session warm) with a cwd whosehasTrustDialogAcceptedistruein~/.claude.json. Side note for anyone else debugging this message: if the PR's repo root is registered withhasTrustDialogAccepted: falsein~/.claude.json(background/non-interactive agents can register folders that way), the widget shows this same message without ever checking gh — fixing that flag was necessary but not sufficient on my machine.checkGhAvailablelog lines, no further gh spawns through the shim, andLocalSessions.getPrChecksis never invoked at all. Whatever the renderer's availability query computes at launch is cached for the app's lifetime, and the two automation checkboxes stay disabled.Possibly the trigger (matches #59182): my session cwd is a parent folder that contains multiple repos but is itself not a git repository; the bound PRs belong to a repo one level below. If the availability probe or the PR lookup runs any git operation against the session cwd, it would fail there and may be mapped to this generic gh message.
Timing datapoint: on this same machine the GitHub REST/auth layer demonstrably worked on Jun 9 (GhRestClient GraphQL responses in
main.log); the widget is consistently broken on the July builds.Ruled out: Full Disk Access / macOS TCC, system proxy (none configured),
/etc/hostsentries,ghhosts.yml (github.com is default-known), API rate limiting (4991/5000 remaining), and stale renderer persistence (no persisted query cache on disk — the wrong verdict is recomputed fresh on every launch).Happy to run further diagnostics if useful.
Windows datapoint with a confirmed fix — likely a different trigger than
@imartinez-traackr's, which I think supports the theory that this one string
has several distinct causes behind it.
Environment: Claude desktop 1.24012.9 (bundled CLI 2.1.219), Windows 11 Pro
26200, installed as an MSIX/Store package
(
C:\Program Files\WindowsApps\Claude_1.24012.9.0_x64__pzs8sxrjxfjjc).gh 2.93.0 at
C:\Program Files\GitHub CLI\gh.exe, on the Machine PATH.Fix:
gh auth login --hostname github.com --insecure-storage. The widgetpopulated immediately. Notably gh reported
You were already logged in to this— the identity never changed, only the token's storage backendaccount
(keyring → plaintext
hosts.yml).Why I think it's the credential store, not the token:
hosts.ymlwas 92 bytes:github.com:/users:and notoken at all. The token was keyring-only.
gh auth statusandgh pr checks <PR>(20+ checks returned) both succeeded from a normal shell while the widget
was reporting unavailable.
--insecure-storage,hosts.ymlis 216 bytes withoauth_token, andgh auth statusreports the source as the file rather than(keyring).ghprocess that can't reach thecredential store still finds the account and prints
X Failed to log in to github.com account <user> (keyring)— which isneither "not installed" nor "not authenticated".
On the message itself. In
resources/ion-dist/assets/v1/c360a9e1c-*.jsthe popover renders five states —
gh_not_installed,gh_not_authenticated,rate_limited,network, andunknown(which renderse.detail) — with"Check that
ghis installed and authenticated." as the??fallback when thereason is absent or
unknowncarries no detail. So the app was never claiminggh was missing; it was saying it didn't know. gh's own stderr names the cause
exactly and appears to be discarded.
Two suggestions, both cheap:
unknown'sdetail— the renderer alreadydisplays it, it's just arriving empty. That alone would have made this
self-diagnosing.
the fallback's advice is actively misleading often enough that it may be
worth making it non-committal ("couldn't determine CI status") rather than
naming a cause it hasn't verified.
Corroborates @imartinez-traackr's point 4: the check is cached per app launch,
so a restart was required after re-authenticating before the widget updated.