xai-org/grok-build · error

no artifact at {base}/{object_name}

Error message

no artifact at {base}/{object_name}

What it means

download_cli_artifact_from_gcs tries a set of candidate URLs (signed/plain) to fetch the CLI artifact; if every attempt fails it surfaces the last error, or this fallback error when no URL was even attempted. It means the updater could not download the CLI artifact from the given GCS base URL + object name — either nothing was retrievable or the candidate list was empty.

Source

Thrown at crates/codegen/xai-grok-update/src/auto_update.rs:1436

        match download_and_decode(&url, dest, codec, with_progress).await {
            Ok(()) => return Ok(()),
            Err(e) => tracing::debug!("compressed .{suffix} unusable, trying next: {e}"),
        }
    }

    let mut plain = Vec::new();
    #[cfg(windows)]
    plain.push(format!("{base}/{object_name}.exe"));
    plain.push(format!("{base}/{object_name}"));

    let mut last_err = None;
    for url in &plain {
        match download_plain(url, dest, with_progress).await {
            Ok(()) => return Ok(()),
            Err(e) => last_err = Some(e),
        }
    }
    Err(last_err.unwrap_or_else(|| anyhow::anyhow!("no artifact at {base}/{object_name}")))
}

/// Returns the version that was actually activated.
async fn install_internal(target: Option<&str>, update_config: &UpdateConfig) -> Result<String> {
    let bases = crate::version::cli_base_urls();
    let base_refs: Vec<&str> = bases.iter().map(String::as_str).collect();
    install_internal_from_bases(target, update_config, &base_refs).await
}

/// Try the base-dependent install phase ([`download_verified_from_base`]:
/// version resolution, download, smoke test) against each base URL in turn,
/// falling through to the next on any failure. Used to keep installs working
/// when the primary CDN endpoint (Cloudflare) is unreachable but the fallback
/// (direct GCS) still resolves.
///
/// Download-phase side effects (download dir creation, binary fetch) are
/// idempotent, so retrying with a different base after a partial failure is
/// safe. Smoke-test failures ([`SmokeTestFailure`]) are a property of the

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Verify the artifact actually exists at {base}/{object_name} (open the URL in a browser or gsutil ls)
  2. Check network/proxy access to the GCS bucket from this machine
  3. Retry later if a release was just cut — artifacts can lag the version pointer
  4. Use a known-good base URL or channel where the artifact is published
Defensive patterns

Strategy: retry

Validate before calling

let head = reqwest::Client::new().head(format!("{base}/{object_name}")).send().await?;
if !head.status().is_success() { anyhow::bail!("artifact missing at {base}/{object_name}"); }

Try / catch

match download_cli_artifact_from_gcs(base, object_name, dest, false).await {
    Err(e) if e.to_string().starts_with("no artifact at") => {
        eprintln!("artifact not published yet, retry later");
    }
    Err(e) => return Err(e),
    Ok(()) => {}
}

Prevention

When it happens

Trigger: Calling download_cli_artifact_from_gcs where all download_plain calls on the generated URLs fail (404 on the artifact object, network errors, permission denied), leaving last_err None in the degenerate empty-URL case.

Common situations: GCS bucket missing the artifact for a specific version/platform (e.g. new release not yet uploaded); wrong gcs_base_url configuration; corporate proxy/firewall blocking storage.googleapis.com; platform object not published yet.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/a5b1ee45e52530c0. Report an issue: GitHub.