Reliably drive the GitHub gh CLI for issue, PR, and label operations in automation and subagent environments, with pre-flight verification so you never fabricate a success or a fake issue URL.
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Um comando direto ignora o prompt de revisão. Verifique a origem antes de executá-lo.
Reliably drive the GitHub gh CLI for issue, PR, and label operations in automation and subagent environments, with pre-flight verification so you never fabricate a success or a fake issue URL.
{"entry_point":{"summary":"Reliably drive the GitHub gh CLI for issue/PR/label work, with pre-flight auth verification so you never fabricate a success.","when_to_use":"When creating, listing, editing, or closing GitHub issues/PRs/labels via gh, especially inside automation or a subagent shell.","quick_start":"1. Run gh auth status and gh repo view BEFORE any op. 2. If auth fails, STOP and report the exact error. 3. Use --json/--jq to parse and confirm results."}}
GitHub gh CLI
Reliable patterns for using the GitHub gh CLI for issue, PR, and label operations — built for automation and subagent environments where silent auth failures are common and fabricating a result is the worst outcome.
When to Use: Any time you create, list, view, edit, or close GitHub issues / PRs / labels through gh, particularly inside a sandboxed shell or a delegated subagent.
The One Rule: Never Fabricate
When an operation cannot be verified as succeeded, report the failure with the exact error. Never invent an issue number, a URL, or a "created successfully" message. A loud, accurate failure is always better than a fake success — downstream agents and humans act on what gets reported.
1. Pre-flight Verification (run BEFORE any operation)
Always confirm authentication and repo access first. These are cheap, read-only, and catch the overwhelming majority of failures before you mutate anything.
# 1. Confirm you are authenticated and see which account/scopes are active
gh auth status
# 2. Confirm you can actually reach the target repo (proves token + SSO + network)
gh repo view <org>/<repo> --json name,url
If gh auth status reports "not logged into any GitHub hosts" or any error, STOP. Do not run create/edit/close. Diagnose using the sections below, then report the exact error verbatim.
If gh repo view fails (404, SAML, Bad credentials), STOP. The token may be valid but lack access to this org/repo. Report the exact error.
Only proceed to mutating operations once both commands succeed.
In a subagent: treat a failed pre-flight as a hard stop. Returning "I created issue #42" when auth failed is the failure mode this skill exists to prevent.
2. Gotcha: Sandbox / OS keychain access
gh's OAuth (keyring) tokens are stored in the OS keychain (macOS Keychain, Linux Secret Service). A sandboxed shell cannot read the keychain, so gh falls back to "no credentials found" and reports "not logged into any GitHub hosts" — even though valid credentials exist.
Symptom: gh auth status says not logged in, but the same command works in a normal terminal.
Fix: Run gh with the sandbox disabled so it can reach the keychain.
In Claude Code, set dangerouslyDisableSandbox: true on the Bash tool call that runs gh.
Re-run the pre-flight (gh auth status) with the sandbox disabled to confirm before proceeding.
3. Gotcha: stale GH_CONFIG_DIR
gh reads its config (including which hosts.yml holds credentials) from GH_CONFIG_DIR if that env var is set, otherwise from ~/.config/gh. A stale or wrong GH_CONFIG_DIR pointing at a nonexistent directory makes gh report "not logged in" even when valid keyring credentials exist elsewhere.
Diagnose:
echo"$GH_CONFIG_DIR"# Is it set? To what?ls"$GH_CONFIG_DIR"# Does the directory exist? Has hosts.yml?
Find the config dir that actually has credentials:
find ~ -maxdepth 5 -name hosts.yml -path '*gh*'
Fix — point GH_CONFIG_DIR at the real config dir, or unset it to fall back to the default:
# Option A: point at the working config explicitly
GH_CONFIG_DIR=/path/to/real/gh-config gh auth status
# Option B: unset to use ~/.config/ghunset GH_CONFIG_DIR && gh auth status
4. Multiple accounts
gh auth status may list several accounts, with one marked active. gh uses the active account. If the active one lacks access to your target org/repo, switch:
gh auth status # see all accounts; note which is "Active account: true"
gh auth switch -u <username> # make the correct account active
gh repo view <org>/<repo> --json name,url # re-verify after switching
5. Gotcha: Org SAML SSO rejects PATs
Personal Access Tokens pulled from .env files are frequently rejected by orgs that enforce SAML SSO:
HTTP 403: Resource protected by organization SAML enforcement.
You must grant your Personal Access token access to this organization.
Why: Even a valid PAT must be SSO-authorized for that specific org via a browser grant. Tokens injected from .env in a headless environment usually have never been through that grant.
Preferred fix: Use a keyring OAuth token (gh auth login) that has already been SSO-authorized for the org — OAuth logins prompt for the SSO grant interactively. To authorize an existing PAT, complete the org's SSO browser grant in GitHub settings (Developer settings → PATs → Configure SSO).
Rule of thumb: For SSO-enforced orgs, prefer keyring OAuth over .env PATs.
6. Server-side fallback for CI / bulk operations
When local auth is unavailable, unreliable, or you need robust bulk operations, run gh from a server that holds a GitHub App installation token. App installation tokens are SSO-exempt and scoped to the installation, making them the most reliable path for automation.
A common pattern is to dispatch the command to a server via AWS SSM:
This section documents a concrete, worked example of the failure modes above — diagnosed while ticketing subagents could not create issues in duettoresearch/code-intelligence. The generic instructions above are what you apply; this is the case study showing how they combine in practice.
Symptom
Ticketing subagents reported "not logged into any GitHub hosts" and "Bad credentials" and could not create issues in duettoresearch/code-intelligence. Some runs would otherwise have been tempted to report a fabricated issue URL — do not.
Root causes found (multiple, compounding)
Stale GH_CONFIG_DIR — subagents inherited GH_CONFIG_DIR=/Users/masa/.config/gh-duetto, a directory that does not exist, so gh saw no credentials. (See §3.)
Sandbox blocked keychain — the Bash sandbox prevented reading the OS keychain, producing the false "not logged in." (See §2.)
.env.local PAT blocked by SAML SSO — the PAT in .env.local is rejected by duettoresearch org SAML enforcement. (See §5.)
Stale keychain token — a leftover keychain token for account bobmatnyc returned HTTP 401 Bad credentials. (See §4 — wrong active account.)
Working configuration (verified)
GH_CONFIG_DIR=/Users/masa/.config/gh-personal # real config dir with valid hosts.yml
sandbox: disabled # so gh can read the keychain
active account: bob-duetto # scopes: gist, read:org, repo, workflow
result: gh repo view duettoresearch/code-intelligence → succeeds
Canonical fix recipe
# Run gh with the real config dir AND the sandbox disabled# (in Claude Code: dangerouslyDisableSandbox: true on the Bash call)
GH_CONFIG_DIR=/Users/masa/.config/gh-personal gh auth status
# If the wrong account is active, switch first:
GH_CONFIG_DIR=/Users/masa/.config/gh-personal gh auth switch -u bob-duetto
# Then re-verify before any mutation:
GH_CONFIG_DIR=/Users/masa/.config/gh-personal gh repo view duettoresearch/code-intelligence --json name,url
Only after that pre-flight succeeds should the subagent run gh issue create etc. — and it must report the real returned URL, never a fabricated one.
Anti-Patterns
❌ Don't: report success without verifying
gh issue create ... # exit code ignored# "Created issue #42!" ← fabricated; the command may have failed silently
✅ Do: capture and confirm the result
url=$(gh issue create --repo <org>/<repo> --title "T" --body "B")
echo"Created: $url"# report the actual returned URL, or the actual error
❌ Don't: assume "not logged in" means no credentials
It usually means sandbox/keychain or a stale GH_CONFIG_DIR — diagnose first (§2, §3).
❌ Don't: rely on .env PATs for SSO-enforced orgs
Prefer keyring OAuth or a server-side App installation token (§5, §6).
Summary
Pre-flight first: gh auth status + gh repo view before any op.
Never fabricate: report the exact error on failure; report the real URL on success.
Know the four failure modes: sandbox/keychain, stale GH_CONFIG_DIR, multiple accounts, SAML SSO PAT rejection.
Automation path: server-side GitHub App installation token (SSO-exempt) for CI/bulk.