gitbutlerapp/gitbutler · error

Failed to fetch nightly release information. HTTP

Error message

Failed to fetch nightly release information. HTTP {response_code}

What it means

Nightly release lookup in the installer: the HTTP fetch of release metadata did not return 200, even though the curl transfer itself succeeded (proxy/redirect handling already passed). Typical causes are a 404 because no nightly build exists for the request or a 5xx from the hosting service; the status code is embedded to distinguish a missing release from a server problem.

Solutions

  1. Retry after a delay — nightlies are published periodically
  2. Fall back to the latest stable release
  3. Check rate-limit headers and add authentication or wait for the window to reset
  4. Verify the nightly release exists on the releases page

Example fix

null
Defensive patterns

Strategy: retry

Validate before calling

// check the nightly release exists before installing
let status = reqwest::Client::new()
    .head("https://api.github.com/repos/OWNER/REPO/releases/tags/nightly")
    .send().await?.status();
let nightly_available = status == reqwest::StatusCode::OK;

Try / catch

match result {
    Err(e) if e.to_string().contains("nightly release information") => {
        // retry with backoff, then fall back to latest stable
    }
    other => other?,
}

Prevention

When it happens

Trigger: VersionRequest::Nightly with the nightly release endpoint returning 404 (nightly deleted/not yet published), 403 (rate limit), or 5xx.

Common situations: Requesting nightly before the first nightly of the day is published, nightly artifact cleanup removed it, unauthenticated GitHub API rate limiting on CI, transient outages.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/ba206bd0954a5c23. Report an issue: GitHub.

Appendix: source

Thrown at crates/but-installer/src/release.rs:58

            .context("Failed to set write function")?;
        transfer
            .perform()
            .with_context(|| format!("Failed to fetch release information from {url}"))?;
    }

    let response_code = easy
        .response_code()
        .context("Failed to get response code")?;

    if response_code != 200 {
        match &config.version_request {
            crate::config::VersionRequest::Specific(version) => {
                bail!(
                    "Failed to fetch release information for version {version}. Version may not exist. HTTP {response_code}"
                );
            }
            crate::config::VersionRequest::Nightly => {
                bail!("Failed to fetch nightly release information. HTTP {response_code}");
            }
            crate::config::VersionRequest::Release => {
                bail!("Failed to fetch release information from {url}. HTTP {response_code}");
            }
        }
    }

    // Validate the effective URL after following redirects
    // This protects against malicious redirects to untrusted domains or insecure protocols
    let effective_url = easy
        .effective_url()
        .context("Failed to get effective URL")?
        .ok_or_else(|| anyhow!("Effective URL is missing"))?;

    validate_api_url(effective_url).with_context(|| {
        format!("Release API was redirected to an untrusted URL: {effective_url}")
    })?;

View on GitHub (pinned to 58e5313667)