google-gemini/gemini-cli · error · RuntimeError

Failed to fetch PR #{pr_number} from GitHub API ({resp.statu

Error message

Failed to fetch PR #{pr_number} from GitHub API ({resp.status_code}): {resp.text}

What it means

This RuntimeError is raised by get_pr_details() when the GitHub REST API GET to /repos/{owner}/{repo}/pulls/{pr_number} returns a non-200 status. The function fetches PR metadata first, then a separate diff request; this guard is on the metadata fetch. The error message surfaces the status code and body to diagnose auth, rate-limit, or not-found conditions.

Source

Thrown at tools/caretaker-agent/evals/triage/helpers/github_api.py:49

    data = resp.json()
    return {
        "owner": owner,
        "repo": repo,
        "number": data.get("number"),
        "title": data.get("title", ""),
        "body": data.get("body", "") or "",
        "createdAt": data.get("created_at", ""),
        "labels": data.get("labels", [])
    }


def get_pr_details(owner: str, repo: str, pr_number: int) -> Dict[str, Any]:
    """Queries GitHub REST API for PR details (title, body, baseRefOid, patch/diff)."""
    url = f"https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}"
    headers = _get_github_headers()
    resp = requests.get(url, headers=headers, timeout=15)
    if resp.status_code != 200:
        raise RuntimeError(f"Failed to fetch PR #{pr_number} from GitHub API ({resp.status_code}): {resp.text}")
    
    data = resp.json()
    
    # Fetch unified patch/diff
    diff_url = f"https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}"
    diff_headers = headers.copy()
    diff_headers["Accept"] = "application/vnd.github.v3.diff"
    diff_resp = requests.get(diff_url, headers=diff_headers, timeout=15)
    diff_content = diff_resp.text if diff_resp.status_code == 200 else ""

    return {
        "number": data.get("number"),
        "title": data.get("title", ""),
        "body": data.get("body", "") or "",
        "baseRefOid": data.get("base", {}).get("sha", ""),
        "diff": diff_content
    }

View on GitHub (pinned to 5024443c72)

Solutions

  1. Confirm the PR exists: open https://github.com/{owner}/{repo}/pull/{pr_number} in a browser.
  2. Set/refresh GITHUB_TOKEN with repo scope for private repositories.
  3. If rate-limited (403/429), reduce concurrency or wait for X-RateLimit-Reset.
  4. Ensure you pass a PR number, not an issue number; use get_issue_details for issues.
  5. Add retry with backoff for 5xx transient failures.

Example fix

# before: passing an issue number where a PR is expected
pr = get_pr_details(owner, repo, issue_number)
# after: resolve the linked PR number first
pr = get_pr_details(owner, repo, linked_pr_number)
Defensive patterns

Strategy: retry

Validate before calling

import os, requests

def can_fetch_pr(owner: str, repo: str, pr_number: int) -> bool:
    headers = {'Accept': 'application/vnd.github.v3+json'}
    token = os.environ.get('GITHUB_TOKEN') or os.environ.get('GH_TOKEN')
    if token:
        headers['Authorization'] = f'Bearer {token}'
    resp = requests.get(f'https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}', headers=headers, timeout=15)
    return resp.status_code == 200

Try / catch

import time
from evals.triage.helpers.github_api import get_pr_details

for attempt in range(3):
    try:
        pr = get_pr_details(owner, repo, pr_number)
        break
    except RuntimeError as e:
        if '403' in str(e) or '429' in str(e):
            time.sleep(2 ** attempt)
        else:
            raise
else:
    raise RuntimeError(f'Could not fetch PR {pr_number} after retries')

Prevention

When it happens

Trigger: Calling get_pr_details(owner, repo, pr_number) with a non-existent PR number (404), an expired token (401), a rate-limited token (403/429), or a pr_number that is actually an issue (the pulls endpoint returns 404 for non-PRs). The owner/repo is private and no token is set.

Common situations: Confusing an issue number with a PR number. Token lacking repo scope for a private repo. GitHub rate limit exhausted after fetching many issues in a batch eval. Stale PR number after the PR was deleted or the repo renamed.

Related errors


AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12). Data as JSON: /api/errors/893124e169d8216f. Report an issue: GitHub.