BigPizzaV3/CodexPlusPlus · error · anyhow::Error

读取安装包失败:{error}

Error message

读取安装包失败:{error}

What it means

The final download stage reads the body with response.bytes().await; if the stream fails mid-body (connection reset, read timeout, proxy truncation) the error becomes "读取安装包失败:{error}" and is logged as update.download.body_failed. Headers were fine and the status was 2xx — the transfer itself broke after starting.

Source

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

    };
    let response = match response.error_for_status() {
        Ok(response) => response,
        Err(error) => {
            let _ = crate::diagnostic_log::append_diagnostic_log(
                "update.download.bad_status",
                json!({ "version": release.version, "assetName": release.asset_name, "error": error.to_string() }),
            );
            return Err(anyhow::anyhow!("下载安装包失败:{error}"));
        }
    };
    let bytes = match response.bytes().await {
        Ok(bytes) => bytes,
        Err(error) => {
            let _ = crate::diagnostic_log::append_diagnostic_log(
                "update.download.body_failed",
                json!({ "version": release.version, "assetName": release.asset_name, "error": error.to_string() }),
            );
            return Err(anyhow::anyhow!("读取安装包失败:{error}"));
        }
    };
    let _ = crate::diagnostic_log::append_diagnostic_log(
        "update.download.completed",
        json!({
            "version": release.version,
            "assetName": release.asset_name,
            "bytes": bytes.len()
        }),
    );
    let installer_path = match download_asset_to(release, &bytes, download_dir) {
        Ok(path) => path,
        Err(error) => {
            let _ = crate::diagnostic_log::append_diagnostic_log(
                "update.write.failed",
                json!({
                    "version": release.version,
                    "assetName": release.asset_name,

View on GitHub (pinned to 1f431ae49b)

Solutions

  1. Simply retry — transient truncation is the most common cause
  2. Use a stabler network or bypass the interfering proxy/VPN for the download
  3. If you instrument the flow, compare the downloaded size with the Content-Length header
  4. Raise UPDATE_DOWNLOAD_TIMEOUT when building from source for consistently slow links
Defensive patterns

Strategy: retry

Try / catch

for attempt in 0..3u32 {
    match perform_update(&release, &dir).await {
        Ok(install) => return Ok(install),
        Err(e) if e.to_string().contains("读取安装包失败") && attempt < 2 => {
            tokio::time::sleep(std::time::Duration::from_secs(1 << attempt)).await;
        }
        Err(e) => return Err(e),
    }
}

Prevention

When it happens

Trigger: Connection reset during a large installer download; the full request (including body) exceeding UPDATE_DOWNLOAD_TIMEOUT; a proxy closing the stream early so the received size never matches Content-Length.

Common situations: Flaky Wi-Fi or VPN on large installers; mobile tethering; aggressive corporate proxies; on-access virus scanners aborting long streams.

Related errors


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