Skip to content

doctor: "gh — found but NOT authenticated" is a false positive when a SECOND gh host is unreachable #100

Closed

Description

@eharriett0

wt doctor reports ⚠ gh — found but NOT authenticated on a machine where gh is fully authenticated and every gh-backed wt command (claim, release, merge-pr) works.

The cause is that gh auth status exits 1 if any configured host fails, not if the host you care about fails. A machine with a second gh host configured — a GitHub Enterprise instance, a mirror, a stale entry for a host that is now unreachable or behind a VPN — gets exit 1 forever, while github.com is perfectly healthy.

Reproduction (v0.1.11)

Two hosts in gh: github.com (logged in, valid token) and a second enterprise host that is currently unreachable.

$ gh auth status
github.com
  ✓ Logged in to github.com account <user> (keyring)
  - Active account: true
  - Token scopes: 'admin:org', 'gist', 'project', 'repo', 'workflow'

<internal-host>
  X Timeout trying to log in to <internal-host> account <user> (keyring)
  - Active account: true

$ echo $?
1

The positive control — the same query scoped to the host wt actually uses:

$ gh auth status --hostname github.com >/dev/null 2>&1; echo $?
0

So the information wt needs is available and unambiguous; the check just asks a broader question than it needs answered.

Why this is worth fixing rather than ignoring

It is the same failure shape as #91: a warning string that cannot distinguish "you are broken" from "the check is broken." An operator reading ⚠ gh — found but NOT authenticated has no way to tell which, and the obvious next step is to re-run gh auth login — re-authenticating a login that was never broken, on the host that was never the problem. On a machine where the second host needs a VPN or an SSO round-trip, that is a genuinely expensive detour.

It also undermines the rest of doctor. The value of a preflight command is that a clean run means something; one line that is permanently and unfixably yellow trains people to skim past all of them.

Suggested fix

Scope the check to the host wt will actually talk to, derived from the remote rather than assumed:

gh auth status --hostname <host-of-origin-remote>

That also does the right thing for a repo hosted on an enterprise instance — today such a repo passes the check for the wrong reason (github.com is fine) while the host it truly needs may not be authenticated at all. So scoping fixes a false negative as well as this false positive.

If deriving the host is more than you want in doctor, --hostname github.com alone would fix the common case, and a fallback that reports which host failed would at least make the message actionable:

⚠ gh — authenticated for github.com; NOT authenticated for <other-host> (not used by this repo)

Note on the check-the-checker principle

I found this while verifying an unrelated block, by not trusting the report: doctor said gh was unauthenticated, yet gh issue view and wt merge-pr had both just succeeded in that same shell. Worth considering as a general rule for doctor — where a capability can be exercised rather than asked about, exercising it is the stronger check, and #91 was the same lesson about hooks.

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