Open-Source Wikis

/

GitHub CLI

/

How to contribute

/

Debugging

cli/cli

Debugging

Toggle verbose API logging

GH_DEBUG=api gh pr list

This routes outgoing HTTP traffic and responses through henvic/httpretty and prints them to stderr. The interceptor is wired in pkg/cmd/factory/default.go via the HTTP transport stack.

GH_DEBUG=true (or any non-empty value other than api) enables generic debug logs, including telemetry payload dumps when telemetry is in log mode.

Useful environment variables

Variable Purpose
GH_DEBUG=api Print HTTP requests/responses with bodies.
GH_DEBUG (any value) Generic debug logging including telemetry log flush.
GH_PROMPT_DISABLED=1 Force non-interactive mode (no prompts).
GH_TOKEN / GITHUB_TOKEN Bypass gh auth login and use a fixed token.
GH_HOST Pin the default host. Useful when testing GHES code paths.
GH_CONFIG_DIR Use a clean config directory for repro.
GH_NO_UPDATE_NOTIFIER Suppress update notification noise during scripted testing.
GH_PAGER=cat / --no-pager Avoid the pager swallowing output.
NO_COLOR=1 Disable ANSI colour.

The full list (and the canonical help text) is in pkg/cmd/root/help_topic.go under gh help environment.

Common errors and what they mean

  • gh auth: not logged in: no token in config, no GH_TOKEN/GITHUB_TOKEN. Run gh auth login or export a token. Triggered by cmdutil.CheckAuth in the root PersistentPreRunE.
  • No default remote repository has been set for this directory: the smart resolver detected multiple matching remotes and the session is non-interactive. Run gh repo set-default to fix it. The logic is in pkg/cmd/factory/remote_resolver.go and default.go.
  • gh: HTTP 401: scope or token problem. The HTTPError.ScopesSuggestion (in api/client.go) appends "(try gh auth refresh -s ...)" suggestions when it can.
  • SSO authorization required: SSO interception in api/http_client.go parses the X-GitHub-SSO header and surfaces the URL. Visit it once, then retry.
  • pending: surfaced via cmdutil.PendingError to indicate an asynchronous action whose result is not yet known. Maps to exit code 8.

Exit codes

internal/ghcmd/cmd.go defines:

Code Meaning
0 (exitOK) Success.
1 (exitError) Generic error.
2 (exitCancel) User cancelled (Ctrl-C, prompt aborted).
4 (exitAuth) Auth-related failure.
8 (exitPending) Asynchronous result pending; not necessarily a failure.

Reproducing CI failures locally

CI uses actions/setup-go matching go.mod. Lint failures are usually reproducible with make lint; test flakes are rare and almost always related to time, network, or cwd. If a test fails only in CI:

  • Check whether it relies on git state (running tests inside a fresh git repo via t.TempDir() is the convention).
  • Check whether iostreams.Test() is configured for the right TTY mode.
  • Check whether httpmock.Registry ordering matters; the default matcher is permissive but not order-sensitive.

Configuration files

gh reads:

  • ~/.config/gh/config.yml - main config (or $GH_CONFIG_DIR).
  • ~/.config/gh/hosts.yml - per-host auth state (token, user, git protocol).
  • The OS keyring (via zalando/go-keyring) for tokens when available.

The structure and migration logic is in internal/config/. To inspect, run gh config list and gh auth status.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Debugging – GitHub CLI wiki | Factory