{"record":{"id":"31a73a59d5a40742","repo":"astrid-runtime/astrid","slug":"label-download-failed-http-status","errorCode":null,"errorMessage":"{label} download failed: HTTP {status}","messagePattern":"(.+?) download failed: HTTP (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/self_update/mod.rs","lineNumber":357,"sourceCode":"fn integrity_manifest_url(release: &serde_json::Value) -> Result<&str, UpdateStageError> {\n    exact_asset_url(release, \"BLAKE3SUMS.txt\")\n        .map_err(|error| UpdateStageError::integrity(error.to_string()))\n}\n\n/// Stream a URL into memory under the size cap.\npub(super) async fn download_bounded(\n    client: &reqwest::Client,\n    url: &str,\n    limit: usize,\n    label: &str,\n) -> anyhow::Result<Vec<u8>> {\n    let mut response = client\n        .get(url)\n        .send()\n        .await\n        .map_err(|_| anyhow::anyhow!(\"{label} download failed\"))?;\n    if !response.status().is_success() {\n        bail!(\"{label} download failed: HTTP {}\", response.status());\n    }\n    if let Some(length) = response.content_length() {\n        let length = usize::try_from(length)\n            .map_err(|_| anyhow::anyhow!(\"{label} exceeds {limit} byte limit\"))?;\n        anyhow::ensure!(length <= limit, \"{label} exceeds {limit} byte limit\");\n    }\n    let mut bytes = Vec::new();\n    while let Some(chunk) = response\n        .chunk()\n        .await\n        .map_err(|_| anyhow::anyhow!(\"{label} download failed\"))?\n    {\n        anyhow::ensure!(\n            chunk.len() <= limit.saturating_sub(bytes.len()),\n            \"{label} exceeds {limit} byte limit\"\n        );\n        bytes.extend_from_slice(&chunk);\n    }","sourceCodeStart":339,"sourceCodeEnd":375,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/self_update/mod.rs#L339-L375","documentation":"`download_bounded` performs a bounded HTTP GET for release artifacts (archives, checksums, manifests) and bails if the server responds with a non-success status. The `{label}` names which artifact failed, making it clear whether it was the binary, signature, or manifest download.","triggerScenarios":"Any caller (download_verify_extract, download, fetch_release_by_tag, resolve_signed_channel) hitting a URL that returns 404 (release/tag or asset missing), 403 (rate-limited or private repo), 5xx (server error), or a redirect to an error page.","commonSituations":"Self-update pointing at a tag that doesn't exist; GitHub rate limiting unauthenticated requests; asset renamed between releases; corporate proxy blocking the download; channel manifest not yet published for a new release.","solutions":["Check the HTTP status in the message: 404 means the tag/asset is missing — verify the release and asset names exist.","Wait and retry on 403/429 (rate limits) or set an auth token if supported.","Verify network/proxy settings can reach the release host.","Pin an older working version or download the artifact manually from the release page."],"exampleFix":"// before\nif !response.status().is_success() {\n    bail!(\"{label} download failed: HTTP {}\", response.status());\n}\n// after\nlet status = response.status();\nif status == reqwest::StatusCode::TOO_MANY_REQUESTS {\n    tokio::time::sleep(Duration::from_secs(30)).await;\n    // retry once\n} else if !status.is_success() {\n    bail!(\"{label} download failed: HTTP {status}\");\n}","handlingStrategy":"retry","validationCode":"curl -fsSI \"$URL\" >/dev/null && echo reachable || echo \"asset missing or host unreachable\"","typeGuard":null,"tryCatchPattern":"let resp = client.get(url).send().await.map_err(|_| anyhow!(\"{label} download failed\"))?;\nlet status = resp.status();\nif status == StatusCode::TOO_MANY_REQUESTS || status.is_server_error() {\n    backoff_retry(up_to = 3);\n} else if !status.is_success() {\n    bail!(\"{label} download failed: HTTP {status}\");\n}","preventionTips":["Verify the release tag and asset names exist before downloading.","Set an auth token where supported to avoid 403 rate limits.","Check corporate proxy/firewall access to the release host.","Retry transient 5xx/429 failures with exponential backoff."],"tags":["network","http","self-update","download","rust"],"backgroundTag":"http-error-response","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}