BigPizzaV3/CodexPlusPlus · error · anyhow::Error

没有可下载的 Release asset

Error message

没有可下载的 Release asset

What it means

perform_update requires a concrete download URL. release.asset_url is populated only when select_update_asset found an asset with platform_asset_rank < 2 (matching OS, native or cross arch) and non-empty name and URL; otherwise it is None and perform_update bails immediately with "没有可下载的 Release asset". The error therefore means: the release/manifest parsed fine, but nothing in its assets list matches the current platform.

Source

Thrown at crates/codex-plus-core/src/update.rs:205

    let update_available = is_newer_version(&release.version, current_version)?;
    Ok(UpdateCheck {
        current_version: current_version.to_string(),
        latest_version: Some(release.version),
        release_summary: release.body,
        asset_name: release.asset_name,
        asset_url: release.asset_url,
        update_available,
    })
}

pub async fn perform_update(
    release: &Release,
    download_dir: &Path,
) -> anyhow::Result<UpdateInstall> {
    let url = release
        .asset_url
        .as_ref()
        .ok_or_else(|| anyhow::anyhow!("没有可下载的 Release asset"))?;
    let _ = crate::diagnostic_log::append_diagnostic_log(
        "update.perform.start",
        json!({
            "version": release.version,
            "assetName": release.asset_name,
            "assetUrl": url,
            "downloadTimeoutSeconds": UPDATE_DOWNLOAD_TIMEOUT.as_secs()
        }),
    );
    let response = match update_http_client()?.get(url).send().await {
        Ok(response) => response,
        Err(error) => {
            let _ = crate::diagnostic_log::append_diagnostic_log(
                "update.download.failed",
                json!({ "version": release.version, "assetName": release.asset_name, "error": error.to_string() }),
            );
            return Err(anyhow::anyhow!("下载安装包失败:{error}"));
        }

View on GitHub (pinned to 1f431ae49b)

Solutions

  1. Verify the release actually contains an asset for your OS+arch with the expected naming (macOS: contains 'codex' and 'plus', ends with .dmg)
  2. Re-run check_for_update to refresh the Release after assets were uploaded or fixed
  3. If self-hosting latest.json, ensure every asset entry has non-empty name and url fields
  4. On platforms without a matching asset, download the appropriate artifact manually instead of calling perform_update

Example fix

// before
let install = perform_update(&release, &dir).await?;

// after
if release.asset_url.is_none() {
    anyhow::bail!(
        "no asset for this platform in release {} (selected asset: {:?})",
        release.version,
        release.asset_name
    );
}
let install = perform_update(&release, &dir).await?;
Defensive patterns

Strategy: type-guard

Validate before calling

if !has_downloadable_asset(&release) {
    anyhow::bail!("no platform asset in release {} — download manually", release.version);
}
let install = perform_update(&release, &dir).await?;

Type guard

fn has_downloadable_asset(release: &codex_plus_core::update::Release) -> bool {
    release.asset_url.as_deref().is_some_and(|u| !u.trim().is_empty())
        && release.asset_name.as_deref().is_some_and(|n| !n.trim().is_empty())
}

Prevention

When it happens

Trigger: Running on Linux while the release only ships .dmg and .exe assets; a latest.json with an empty "assets" array; asset entries whose url/browser_download_url is blank (filtered out by select_update_asset); asset names that fail platform detection (macOS requires a name containing codex and plus, ending with .dmg).

Common situations: A user on a platform without published binaries clicking 'install update'; a release checked before its assets finished uploading; a CI manifest generator listing assets with empty URLs; renamed artifacts breaking platform-name detection.

Related errors


AI-assisted analysis of BigPizzaV3/CodexPlusPlus@1f431ae49b (2026-08-16). Data as JSON: /api/errors/f65348695bf10328. Report an issue: GitHub.