{"record":{"id":"990223ade9d24b7f","repo":"nikivdev/code","slug":"download-failed-with-status","errorCode":null,"errorMessage":"Download failed with status {}","messagePattern":"Download failed with status (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/upgrade.rs","lineNumber":301,"sourceCode":"        if l < c {\n            return false;\n        }\n    }\n\n    latest_parts.len() > current_parts.len()\n}\n\n/// Download a file with progress indication.\nfn download_with_progress(client: &Client, url: &str, dest: &Path) -> Result<()> {\n    let response = client\n        .get(url)\n        .header(\"User-Agent\", format!(\"flow/{}\", current_version()))\n        .timeout(Duration::from_secs(300))\n        .send()\n        .context(\"Failed to start download\")?;\n\n    if !response.status().is_success() {\n        bail!(\"Download failed with status {}\", response.status());\n    }\n\n    let total_size = response.content_length();\n    let mut file = File::create(dest).context(\"Failed to create temp file\")?;\n\n    let bytes = response.bytes().context(\"Failed to read response\")?;\n\n    if let Some(total) = total_size {\n        println!(\"Downloading {} bytes...\", total);\n    }\n\n    file.write_all(&bytes)?;\n    Ok(())\n}\n\nfn github_token() -> Option<String> {\n    for key in [\"GITHUB_TOKEN\", \"GH_TOKEN\", \"FLOW_GITHUB_TOKEN\"] {\n        if let Ok(value) = env::var(key) {","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/upgrade.rs#L283-L319","documentation":"In `download_with_progress` (src/upgrade.rs:292-315), after `reqwest::Client::get(url).send()` succeeds at the HTTP transport level, the code checks `response.status().is_success()` and bails if the release asset server returned a non-2xx status. The upgrade flow aborts because the expected artifact could not be fetched.","triggerScenarios":"Calling `f upgrade` resolves a release asset URL and `client.get(url).send()` returns a 404 (asset/repo missing or renamed), 403 (rate limit, private repo without GITHUB_TOKEN/GH_TOKEN/FLOW_GITHUB_TOKEN), or 5xx.","commonSituations":"Hitting GitHub API rate limits (60 req/hr unauthenticated); upgrading a fork whose releases/assets were deleted; asset name changed between versions; corporate proxy or transient GitHub 5xx; private repository without a token set.","solutions":["Re-run after a few minutes if it was a 429/5xx (rate limit or transient server error).","Set GITHUB_TOKEN (or GH_TOKEN / FLOW_GITHUB_TOKEN) to raise the rate limit and access private repos.","Check that the release and asset actually exist: `gh release view <tag>` or open the repo's releases page.","Verify network/proxy settings (HTTPS_PROXY) can reach github.com / objects.githubusercontent.com.","Update via your package manager instead if the binary was installed that way."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// check reachability & auth before upgrading\ncurl -sI \"$ASSET_URL\" | head -1   # expect HTTP/2 200\necho \"${GITHUB_TOKEN:+token set}\" # avoids 403 rate limits","typeGuard":null,"tryCatchPattern":"match upgrade::run() {\n    Err(e) if e.to_string().contains(\"Download failed with status\") => {\n        eprintln!(\"Asset unavailable: {e}. Check release exists / set GITHUB_TOKEN / retry later.\");\n    }\n    Err(e) => eprintln!(\"upgrade failed: {e}\"),\n    Ok(()) => {}\n}","preventionTips":["Export GITHUB_TOKEN to avoid unauthenticated rate limits (403).","Verify the release/asset exists before scripting upgrades.","Handle 429 with backoff instead of immediate retry.","Check proxy env vars (HTTPS_PROXY) reach GitHub."],"tags":["network","http","download","upgrade"],"backgroundTag":"http-non-2xx-download-failure","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}