Hmbown/CodeWhale · error · anyhow::Error

failed to fetch {description} from {url}

Error message

failed to fetch {description} from {url}

What it means

Defensive fallback arm of fetch_release_json's retry loop: returned only when the loop (1..=UPDATE_HTTP_ATTEMPTS, currently 3) exits without a single attempt recording an error. Every real failure carries a more specific message (HTTP status or transport context); this one has no cause attached and is effectively unreachable in shipped builds.

Source

Thrown at crates/cli/src/update.rs:994

            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 {
    status.is_server_error()
        || status == reqwest::StatusCode::REQUEST_TIMEOUT
        || status == reqwest::StatusCode::TOO_MANY_REQUESTS
}

fn sleep_before_update_retry(attempt: usize) {
    std::thread::sleep(Duration::from_millis(
        UPDATE_HTTP_RETRY_DELAY_MS * attempt as u64,
    ));
}

fn fetch_latest_release_from_url(url: &str, proxy: Option<&Proxy>) -> Result<Release> {
    let body = fetch_release_json(url, "release info", proxy)?;
    let release: Release = serde_json::from_str(&body).with_context(|| {
        format!("failed to parse release JSON from GitHub API. Response: {body}")

View on GitHub (pinned to 8880682c63)

Solutions

  1. Treat it as an internal invariant violation: capture the exact build and file an issue
  2. If you maintain a fork, keep UPDATE_HTTP_ATTEMPTS >= 1
  3. Look for the real failure in preceding errors; this message deliberately carries no cause
Defensive patterns

Strategy: try-catch

Try / catch

Propagate as an internal error without retrying: this message carries no cause, so retry logic cannot be informed by it. Wrap it in a context identifying the caller and report upstream.

Prevention

When it happens

Trigger: Only possible if the loop body never runs, i.e. UPDATE_HTTP_ATTEMPTS was changed to 0 in a modified build, or the loop logic was rewritten. All real transport/HTTP errors surface through the other arms.

Common situations: Practically none; seeing it means the binary was built from modified source (a fork lowered UPDATE_HTTP_ATTEMPTS) or it is being read in code review.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/e56f919a69dd7051. Report an issue: GitHub.