Hmbown/CodeWhale · error · anyhow::Error
failed to fetch {description} from {url}: HTTP {status} {bod
Error message
failed to fetch {description} from {url}: HTTP {status}
{body} What it means
fetch_release_json retrieves release metadata JSON and got an HTTP response with a non-success status; the status and body are embedded for diagnosis. Retryable statuses (5xx, 408, 429) are retried up to 3 times with linear backoff before this surfaces; other 4xx statuses fail immediately.
Source
Thrown at crates/cli/src/update.rs:979
.get(url)
.header(reqwest::header::ACCEPT, "application/vnd.github+json")
.send()
.with_context(|| format!("failed to fetch {description} from {url}"))?;
let status = response.status();
let body = response
.text()
.with_context(|| format!("failed to read {description} response body from {url}"))?;
Ok((status, body))
}
fn fetch_release_json(url: &str, description: &str, proxy: Option<&Proxy>) -> Result<String> {
let mut last_error = None;
for attempt in 1..=UPDATE_HTTP_ATTEMPTS {
match fetch_release_json_once(url, description, proxy) {
Ok((status, body)) if status.is_success() => return Ok(body),
Ok((status, body)) => {
let error =
anyhow!("failed to fetch {description} from {url}: HTTP {status}\n{body}");
if should_retry_http_status(status) && attempt < UPDATE_HTTP_ATTEMPTS {
last_error = Some(error);
sleep_before_update_retry(attempt);
continue;
}
return Err(error);
}
Err(error) if attempt < UPDATE_HTTP_ATTEMPTS => {
last_error = Some(error);
sleep_before_update_retry(attempt);
}
Err(error) => return Err(error),
}
}
Err(last_error.unwrap_or_else(|| anyhow!("failed to fetch {description} from {url}")))
}
fn should_retry_http_status(status: reqwest::StatusCode) -> bool {View on GitHub (pinned to 8880682c63)
Solutions
- Read the HTTP status in the message: 403 with a rate-limit body means wait for the reset window or configure the proxy/token; 404 means verify the feed URL and that the release exists
- If the body contains GitHub rate-limit JSON, honor the reset timestamp and retry after it
- Check HTTP_PROXY/HTTPS_PROXY and Codewhale's proxy setting for a misconfigured intercept
- For 5xx that persisted 3 attempts, retry later; the server side is transiently broken
Example fix
# before: unauthenticated API hammering from CI for i in $(seq 1 100); do codewhale update check; done # after: check once, honor rate limits codewhale update check # retry only after the rate-limit reset reported in the body
Defensive patterns
Strategy: retry
Try / catch
Match on the error, extract the 'HTTP <status>' and body from the message, and branch: for 429/403 parse the rate-limit reset in the body and retry only after it; for 5xx retry with capped backoff; for other 4xx surface immediately with the body text.
Prevention
- Configure Codewhale's proxy setting instead of hammering github.com unauthenticated from shared CI IPs
- Cache release metadata between runs to stay under GitHub rate limits
- Log the response body once per failure, not per retry
When it happens
Trigger: The update-check path fetching a release JSON when the endpoint returns 403 (GitHub unauthenticated rate limit), 404 (wrong repo/tag or removed release), 401, a proxy interception status, or a 5xx that persisted across all 3 attempts.
Common situations: GitHub API rate limiting (60 req/h per IP without a token); corporate proxies or MITM appliances returning 4xx for github.com; an update-feed URL pointing at a wrong repo; a release deleted after metadata was cached.
Related errors
- download failed with HTTP {status}: {body}
- Runtime API request failed (${status}): ${message}
- iLink API ${endpoint} failed: HTTP ${response.status} — ${te
- failed to fetch {description} from {url}
- failed to resolve latest stable release from {url}
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/0f0c83671f90c3cc.
Report an issue: GitHub.