Skip to content

doctor: 'gh NOT authenticated' is false when a SECOND configured host is unreachable — the aggregate gh auth status exit code is the wrong question #102

Closed

Description

@eharriett0

wt doctor reports ⚠ gh — found but NOT authenticated (claim/release/merge-pr need gh auth login) on a machine where gh is authenticated to github.com and every gh call succeeds.

Cause

gh auth status reports all configured hosts and exits non-zero if ANY of them fails — even when the host you actually use is fine. A second host (a self-hosted GitHub Enterprise, an org's internal instance) that is unreachable — VPN down, DNS split-horizon, expired token — makes the whole command exit 1.

$ gh auth status; echo "exit=$?"
github.com
  ✓ Logged in to github.com account <user> (keyring)
  - Active account: true
  - Token scopes: 'admin:org', 'repo', 'workflow', …

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

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

So the aggregate exit code answers "is every configured host healthy?", while doctor is asking "can I use gh for this repo?" — different questions.

Why it matters more than a cosmetic warning

The message names a remedy that is wrong and mildly destructive to follow: gh auth login on a working credential, in a repo where claim / release / merge-pr are in fact working. It is the same shape as #91 — a check that reports its subject as broken when it is fine, and points the operator at a fix for a problem they do not have. I nearly re-authed before running the scoped command.

Being off-VPN is the normal state for a lot of a day, so this is not an edge case for anyone whose org has a second GitHub host configured.

Suggested fix

Scope the check to the host wt will actually talk to, resolved from the repo's origin remote:

  • gh auth status --hostname <host-from-origin> — exits 0/1 for that host alone; or
  • gh auth token --hostname <host> — non-empty means usable; or
  • parse the aggregate output for the specific host's ✓/X line rather than reading $?.

The third is the least appealing (output format is not a contract), but any of them beat the aggregate exit code.

A related nicety: when the scoped check passes but another host is failing, staying silent is right — that other host is not wt's business.

Environment

  • wt v0.1.11, gh 2.x from Homebrew, macOS.
  • Two hosts in hosts.yml; github.com healthy, the other unreachable at the time.

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