`gh pr create` sends empty Authorization header inside Claude Code session (HTTP 401)

Resolved 💬 1 comment Opened Apr 24, 2026 by claytonvlawson Closed May 28, 2026

Summary

gh pr create (and likely other gh subcommands that hit the GraphQL endpoint via the same code path) sends an empty Authorization: header when invoked from inside a Claude Code session, even though gh auth status reports logged-in and the token is valid. Other gh subcommands (gh api, gh auth token, gh api graphql -f query=...) do pick up the token correctly. This means any gh operation that requires auth through that specific code path fails with HTTP 401: Requires authentication until the user falls back to the REST API directly.

Environment

  • Claude Code: 2.1.108 (installed via brew install --cask claude-code)
  • gh: 2.91.0 (from brew install gh)
  • macOS: 15.6.1 (Darwin 24.6.0)
  • User-Agent in failing request: GitHub CLI 2.91.0 Agent/claude-code (the Agent/claude-code suffix is the hint that the claude-code integration layer is involved)
  • Auth scopes present: gist, read:org, repo, workflow
  • No GH_TOKEN or GITHUB_TOKEN env vars set

Repro

  1. gh auth login -h github.com (HTTPS + web flow)
  2. gh auth status shows logged in; gh api user --jq .login returns the username
  3. gh api graphql -f query='query { viewer { login } }' returns {"data":{"viewer":{"login":"..."}}}
  4. gh pr create --repo <owner>/<repo> --base main --head <fork>:<branch> --title test --body test
  5. Fails with: error checking for existing pull request: HTTP 401: Requires authentication (https://api.github.com/graphql)

Debug trace

GH_DEBUG=api gh pr create --repo IyadhKhalfallah/clauditor ...

Output (abridged):

* Request to https://api.github.com/graphql
> POST /graphql HTTP/1.1
> Host: api.github.com
> Accept: application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview
> Authorization: 
> Content-Length: 526
> Content-Type: application/json; charset=utf-8
> User-Agent: GitHub CLI 2.91.0 Agent/claude-code
> X-Github-Api-Version: 2022-11-28

The Authorization: header is present but empty. A fresh gh api graphql -f query=... run immediately before and after does populate the header correctly.

Expected

gh pr create should use the same token resolution path as gh api, picking up the keyring token and sending Authorization: Bearer ghp_... or Authorization: token ghp_... on the GraphQL request.

Workaround

Call the REST API directly and pass the token grabbed from gh auth token:

import json, urllib.request, subprocess
token = subprocess.check_output(['gh', 'auth', 'token']).decode().strip()
payload = json.dumps({
    'title': '...',
    'body': '...',
    'head': '<fork-owner>:<branch>',
    'base': 'main',
}).encode()
req = urllib.request.Request(
    'https://api.github.com/repos/<base-owner>/<repo>/pulls',
    data=payload,
    method='POST',
    headers={
        'Authorization': f'Bearer {token}',
        'Accept': 'application/vnd.github+json',
        'X-GitHub-Api-Version': '2022-11-28',
        'User-Agent': 'gh-api-fallback',
    },
)
resp = urllib.request.urlopen(req)
print(json.loads(resp.read())['html_url'])

This works because it uses the token directly rather than whatever code path gh pr create is going through. Using gh api -X POST repos/<owner>/<repo>/pulls -f title=... -f body=... should also work as a workaround for anyone hitting this without needing to write Python.

Impact

Any automated PR creation from inside a Claude Code session fails silently until the user notices the 401. Since gh auth status reports a healthy login, the failure mode is confusing — it looks like an upstream auth issue rather than a local integration bug.

Related observation

The Agent/claude-code suffix in the User-Agent suggests gh is running through a claude-code-specific wrapper or modified build. The selective-empty-header pattern (some commands fine, pr create not) suggests the wrapper is intercepting some subcommands for permission prompting or other behavior and dropping the Authorization header in the process.

🤖 Filed via Claude Code

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗