{"record":{"id":"050ed898682af3cb","repo":"nikivdev/code","slug":"github-api-returned-status","errorCode":null,"errorMessage":"GitHub API returned status {}: {}","messagePattern":"GitHub API returned status (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/upgrade.rs","lineNumber":204,"sourceCode":"        owner, repo\n    );\n\n    let mut request = client\n        .get(&url)\n        .header(\"User-Agent\", format!(\"flow/{}\", current_version()))\n        .header(\"Accept\", \"application/vnd.github.v3+json\")\n        .timeout(Duration::from_secs(30));\n\n    if let Some(token) = github_token() {\n        request = request.bearer_auth(token);\n    }\n\n    let response = request\n        .send()\n        .context(\"Failed to fetch release info from GitHub\")?;\n\n    if !response.status().is_success() {\n        bail!(\n            \"GitHub API returned status {}: {}\",\n            response.status(),\n            response.text().unwrap_or_default()\n        );\n    }\n\n    response\n        .json::<GitHubRelease>()\n        .context(\"Failed to parse GitHub release response\")\n}\n\n/// Fetch a release by tag (e.g. \"v0.1.0\") from GitHub.\nfn fetch_release_by_tag(client: &Client, tag: &str) -> Result<GitHubRelease> {\n    let (owner, repo) = upgrade_repo()?;\n    let url = format!(\n        \"https://api.github.com/repos/{}/{}/releases/tags/{}\",\n        owner, repo, tag\n    );","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/upgrade.rs#L186-L222","documentation":"Raised by `fetch_latest_release` when the GitHub releases API responds with a non-2xx status. The error embeds the HTTP status code and the (truncated) response body, so it covers rate limiting (403), repo not found (404), auth issues, and 5xx outages.","triggerScenarios":"Calling `fetch_latest_release` (via `run` or `check_for_upgrade_prompt`) when the GET to https://api.github.com/repos/<owner>/<repo>/releases/latest fails: 403 rate limit (unauthenticated GitHub API limit ~60/hr), 404 wrong owner/repo, 401 bad token, 5xx GitHub outage.","commonSituations":"CI servers hammering the API from shared IPs and hitting rate limits; FLOW_UPGRADE_REPO pointing at a renamed or deleted repo; corporate proxies returning error pages; GitHub incidents.","solutions":["If status is 403 with rate-limit body, wait for the rate-limit window to reset or set a GITHUB_TOKEN that the client can use.","Verify the configured owner/repo (FLOW_UPGRADE_REPO) exists and has releases.","Check https://www.githubstatus.com if you see 5xx statuses and retry later.","Check proxy/firewall interference with api.github.com."],"exampleFix":"// before\nlet status = check_for_upgrade_prompt();\n// after\nmatch check_for_upgrade_prompt() {\n    Ok(Some(msg)) => println!(\"{msg}\"),\n    Ok(None) => {}\n    Err(e) if e.to_string().contains(\"403\") => eprintln!(\"rate limited; skipping check\"),\n    Err(e) => eprintln!(\"upgrade check failed: {e}\"),\n}","handlingStrategy":"retry","validationCode":"fn github_reachable() -> bool {\n    reqwest::blocking::get(\"https://api.github.com/rate_limit\")\n        .map(|r| r.status().is_success())\n        .unwrap_or(false)\n}\n// and before calls: check remaining rate limit via /rate_limit endpoint","typeGuard":null,"tryCatchPattern":"for attempt in 0..3 {\n    match fetch_latest_release(owner, repo) {\n        Ok(rel) => { /* use rel */ break; }\n        Err(e) if e.to_string().contains(\"status 5\") && attempt < 2 => {\n            std::thread::sleep(std::time::Duration::from_secs(2 << attempt)); // retry on 5xx\n        }\n        Err(e) if e.to_string().contains(\"status 403\") => {\n            eprintln!(\"GitHub rate limited; set GITHUB_TOKEN or wait\");\n            break;\n        }\n        Err(e) => return Err(e),\n    }\n}","preventionTips":["Monitor the GitHub API rate limit and use an authenticated token where possible.","Cache the latest-release result and check infrequently (e.g. once a day).","Validate FLOW_UPGRADE_REPO points to an existing, public repo.","Treat upgrade checks as advisory: catch errors and continue without failing the CLI."],"tags":["network","github-api","http"],"backgroundTag":"http-non-2xx-response","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}