tonhowtf/omniget · error · anyhow::Error

Failed to open Deno zip

Error message

Failed to open Deno zip: {}

What it means

After downloading the Deno zip into memory, download_deno spawns a blocking task that wraps the bytes in an io::Cursor and opens it with zip::ZipArchive::new. If the byte buffer is not a valid zip (bad End-of-Central-Directory record, truncation, or an error page), the error 'Failed to open Deno zip' is returned.

Solutions

  1. Log the first bytes of `data` and verify the zip magic 'PK\x03\x04' before extraction
  2. Check Content-Type and Content-Length headers match a binary zip before accepting the body
  3. Re-run download_deno to get a fresh copy of the archive
  4. Disable/bypass the intercepting proxy or configure correct proxy settings in http_client::apply_global_proxy
  5. Increase the 300s timeout or stream to disk if network is slow and truncation is the cause

Example fix

// before
let cursor = std::io::Cursor::new(&data);
let mut archive =
    zip::ZipArchive::new(cursor).map_err(|e| anyhow!("Failed to open Deno zip: {}", e))?;
// after
if !data.starts_with(b"PK") {
    let preview = String::from_utf8_lossy(&data[..data.len().min(200)]);
    return Err(anyhow!("Downloaded Deno artifact is not a zip (got: {}) - check proxy/URL", preview));
}
let mut archive = zip::ZipArchive::new(std::io::Cursor::new(&data))
    .map_err(|e| anyhow!("Failed to open Deno zip: {}", e))?;
Defensive patterns

Strategy: validation

Validate before calling

// after reading bytes, before extraction
if !data.starts_with(b"PK\x03\x04") {
    return Err(anyhow!("downloaded body is not a zip - check proxy/URL"));
}

Type guard

fn is_zip_bytes(data: &[u8]) -> bool {
    data.starts_with(b"PK\x03\x04") && data.windows(4).rev().any(|w| w == b"PK\x05\x06")
}

Try / catch

match download_deno().await {
    Err(e) if e.to_string().contains("Failed to open Deno zip") => {
        eprintln!("Deno artifact invalid; clearing cache and retrying");
        // delete cached bytes/file, re-run ensure_js_runtime once
        ensure_js_runtime().await?;
    },
    r => r?,
}

Prevention

When it happens

Trigger: The HTTP body was actually an HTML/text error page or proxy block page saved as the zip; the response was truncated (connection dropped after status check); a redirect was followed to an HTML page.

Common situations: Captive portal or corporate proxy returning HTML; GitHub release asset moved/renamed so a redirect lands on an error page; partial download due to 300s timeout firing mid-body (though that usually errors earlier).

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/e8dfef7450789aac. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/core/dependencies.rs:747

        .build()?;

    let response = client.get(url).send().await?;
    if !response.status().is_success() {
        return Err(anyhow!(
            "Failed to download Deno: HTTP {}",
            response.status()
        ));
    }

    let bytes = response.bytes().await?;
    let data = bytes.to_vec();
    let bin_dir_clone = bin_dir.clone();
    let deno_name_clone = deno_name.clone();

    tokio::task::spawn_blocking(move || {
        let cursor = std::io::Cursor::new(&data);
        let mut archive =
            zip::ZipArchive::new(cursor).map_err(|e| anyhow!("Failed to open Deno zip: {}", e))?;

        for i in 0..archive.len() {
            let mut file = archive
                .by_index(i)
                .map_err(|e| anyhow!("Failed to read zip entry: {}", e))?;

            let name = file.name().to_string();
            if name.ends_with(&deno_name_clone) || name == "deno" || name == "deno.exe" {
                let dest = bin_dir_clone.join(&deno_name_clone);
                let mut buf = Vec::new();
                std::io::Read::read_to_end(&mut file, &mut buf)?;
                std::fs::write(&dest, &buf)?;
                break;
            }
        }

        Ok::<(), anyhow::Error>(())
    })

View on GitHub (pinned to 8600b91f42)