google-gemini/gemini-cli · critical · GitHubClientError
GitHub token is missing. Cannot authorize Pull Request creat
Error message
GitHub token is missing. Cannot authorize Pull Request creation.
What it means
GitHubClientError 'GitHub token is missing. Cannot authorize Pull Request creation.' is raised by create_pull_request when self._token is falsy. The PR endpoint requires a Bearer token; without one the request would 401, so the client fails fast with a clear message before any network call.
Source
Thrown at tools/caretaker-agent/cloudrun/pr-generator/workflow/github_client.py:50
def create_pull_request(
self, branch_name: str, title: str, body: str
) -> str:
"""Submits a POST request to GitHub to create a new Pull Request.
Args:
branch_name: The feature branch to be merged.
title: Title of the Pull Request.
body: Body description markdown of the Pull Request.
Returns:
The PR number of the successfully created Pull Request as a string.
Raises:
GitHubClientError: If the HTTP request fails or token is missing.
"""
if not self._token:
raise GitHubClientError(
"GitHub token is missing. Cannot authorize Pull Request creation."
)
data = {
"title": title,
"body": body,
"head": branch_name,
"base": "main",
}
req = urllib.request.Request(
self._base_url,
data=json.dumps(data).encode("utf-8"),
headers={
"Accept": "application/vnd.github+json",
"Authorization": f"Bearer {self._token}",
"X-GitHub-Api-Version": "2022-11-28",
"Content-Type": "application/json",View on GitHub (pinned to 5024443c72)
Solutions
- Set GH_TOKEN (or whichever var the GitHubClient is constructed from) in the CloudRun service env / secret mount.
- Construct GitHubClient with a non-empty token: GitHubClient(token=os.environ['GH_TOKEN'], owner=..., repo=...).
- Add a startup assertion that the token is present so the failure surfaces at boot, not at first PR.
Example fix
# before
client = GitHubClient(token=os.environ.get('GH_TOKEN'), owner=o, repo=r)
# after
token = os.environ['GH_TOKEN'] # KeyError surfaces the missing secret early
client = GitHubClient(token=token, owner=o, repo=r) Defensive patterns
Strategy: validation
Validate before calling
token = os.environ.get('GH_TOKEN') or os.environ.get('GITHUB_TOKEN')
if not token:
raise SystemExit('GH_TOKEN env var required to create PRs') Type guard
def is_missing_github_token(e: Exception) -> bool:
return isinstance(e, GitHubClientError) and 'token is missing' in str(e).lower() Try / catch
try:
pr_number = client.create_pull_request(branch, title, body)
except GitHubClientError as e:
if 'token is missing' in str(e): raise SystemExit('configure GH_TOKEN secret')
raise Prevention
- Mount the GitHub token as a Cloud Run secret and assert it at startup.
- Construct GitHubClient only after confirming the token is non-empty.
When it happens
Trigger: GitHubClient(token=None or '') constructed -> create_pull_request(...) -> `if not self._token: raise GitHubClientError(...)` at line 49-52, before building the urllib Request.
Common situations: GH_TOKEN/GITHUB_TOKEN env var not injected into the CloudRun service; secret name typo in the deploy config; token injected as empty string; the workflow's token-load step ran before the env var was exported.
Related errors
- Failed to fetch issue #{issue_number} from GitHub API ({resp
- Failed to fetch PR #{pr_number} from GitHub API ({resp.statu
- Failed to initialize GCS bucket ${this.bucketName}: ${error}
- Failed to install extension ${installMetadata.source}: ${res
- Invalid response code downloading ${endpoint}: ${response.st
AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12).
Data as JSON: /api/errors/1e8b214d0f0a3661.
Report an issue: GitHub.