nikivdev/code · error
GitHub API returned status {}: {}
Error message
GitHub API returned status {}: {} What it means
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.
Source
Thrown at src/upgrade.rs:204
owner, repo
);
let mut request = client
.get(&url)
.header("User-Agent", format!("flow/{}", current_version()))
.header("Accept", "application/vnd.github.v3+json")
.timeout(Duration::from_secs(30));
if let Some(token) = github_token() {
request = request.bearer_auth(token);
}
let response = request
.send()
.context("Failed to fetch release info from GitHub")?;
if !response.status().is_success() {
bail!(
"GitHub API returned status {}: {}",
response.status(),
response.text().unwrap_or_default()
);
}
response
.json::<GitHubRelease>()
.context("Failed to parse GitHub release response")
}
/// Fetch a release by tag (e.g. "v0.1.0") from GitHub.
fn fetch_release_by_tag(client: &Client, tag: &str) -> Result<GitHubRelease> {
let (owner, repo) = upgrade_repo()?;
let url = format!(
"https://api.github.com/repos/{}/{}/releases/tags/{}",
owner, repo, tag
);View on GitHub (pinned to a747e741ae)
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.
Example fix
// before
let status = check_for_upgrade_prompt();
// after
match check_for_upgrade_prompt() {
Ok(Some(msg)) => println!("{msg}"),
Ok(None) => {}
Err(e) if e.to_string().contains("403") => eprintln!("rate limited; skipping check"),
Err(e) => eprintln!("upgrade check failed: {e}"),
} Defensive patterns
Strategy: retry
Validate before calling
fn github_reachable() -> bool {
reqwest::blocking::get("https://api.github.com/rate_limit")
.map(|r| r.status().is_success())
.unwrap_or(false)
}
// and before calls: check remaining rate limit via /rate_limit endpoint Try / catch
for attempt in 0..3 {
match fetch_latest_release(owner, repo) {
Ok(rel) => { /* use rel */ break; }
Err(e) if e.to_string().contains("status 5") && attempt < 2 => {
std::thread::sleep(std::time::Duration::from_secs(2 << attempt)); // retry on 5xx
}
Err(e) if e.to_string().contains("status 403") => {
eprintln!("GitHub rate limited; set GITHUB_TOKEN or wait");
break;
}
Err(e) => return Err(e),
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- device auth start failed: HTTP {}
- device auth poll failed: HTTP {}
- Maple MCP request failed ({}): {}
- remote review failed: HTTP {}
- hub returned error: {}
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/050ed898682af3cb.
Report an issue: GitHub.