{"record":{"id":"b80a7f2150be5f08","repo":"tonhowtf/omniget","slug":"failed-to-open-aria2c-zip","errorCode":null,"errorMessage":"Failed to open aria2c zip: {}","messagePattern":"Failed to open aria2c zip: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/dependencies.rs","lineNumber":911,"sourceCode":"\n    let response = client.get(url).send().await?;\n    if !response.status().is_success() {\n        return Err(anyhow!(\n            \"Failed to download aria2c: HTTP {}\",\n            response.status()\n        ));\n    }\n\n    let bytes = response.bytes().await?;\n\n    let data = bytes.to_vec();\n    let bin_dir_clone = bin_dir.clone();\n    let aria2c_name_clone = aria2c_name.clone();\n\n    tokio::task::spawn_blocking(move || {\n        let cursor = std::io::Cursor::new(&data);\n        let mut archive = zip::ZipArchive::new(cursor)\n            .map_err(|e| anyhow!(\"Failed to open aria2c zip: {}\", e))?;\n\n        for i in 0..archive.len() {\n            let mut file = archive\n                .by_index(i)\n                .map_err(|e| anyhow!(\"Failed to read zip entry: {}\", e))?;\n\n            let name = file.name().to_string();\n            if name.ends_with(&aria2c_name_clone) {\n                let dest = bin_dir_clone.join(&aria2c_name_clone);\n                let mut buf = Vec::new();\n                std::io::Read::read_to_end(&mut file, &mut buf)?;\n                std::fs::write(&dest, &buf)?;\n                break;\n            }\n        }\n\n        Ok::<(), anyhow::Error>(())\n    })","sourceCodeStart":893,"sourceCodeEnd":929,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/dependencies.rs#L893-L929","documentation":"Thrown in download_aria2c when zip::ZipArchive::new cannot parse the downloaded aria2c Windows release archive. The bytes fetched from the GitHub release URL are not a structurally valid ZIP file (bad signature, truncated body, corrupted transfer). The anyhow context preserves the underlying zip crate error message.","triggerScenarios":"The HTTP response body downloaded from https://github.com/aria2/aria2/releases/... is not a valid zip: a proxy or captive portal returned an HTML error page, the download was truncated by the 120s timeout, disk/memory corruption, or GitHub returned a redirect/error body with a 2xx status.","commonSituations":"Corporate proxies intercepting github.com and returning HTML; flaky networks truncating the response; the pinned release URL (release-1.37.0) becoming unavailable and a CDN returning a soft-error 200 page; running behind an HTTP proxy with global proxy settings misconfigured.","solutions":["Re-run ensure_aria2c / download_aria2c — a truncated download usually succeeds on retry","Check proxy configuration (apply_global_proxy source) and corporate firewall rules for github.com","Verify the downloaded bytes: check first bytes for the PK zip signature (0x50 0x4B) and Content-Length before parsing","Manually download the aria2 zip and place aria2c.exe in the managed bin directory so download is skipped","Update the pinned release URL if release-1.37.0 was removed or moved"],"exampleFix":"// before\nlet cursor = std::io::Cursor::new(&data);\nlet mut archive = zip::ZipArchive::new(cursor)\n    .map_err(|e| anyhow!(\"Failed to open aria2c zip: {}\", e))?;\n// after\nif data.len() < 4 || &data[..2] != b\"PK\" {\n    return Err(anyhow!(\"Downloaded aria2c payload is not a zip ({} bytes)\", data.len()));\n}\nlet cursor = std::io::Cursor::new(&data);\nlet mut archive = zip::ZipArchive::new(cursor)\n    .map_err(|e| anyhow!(\"Failed to open aria2c zip: {}\", e))?;","handlingStrategy":"retry","validationCode":"// Rust: sanity-check payload before extraction\nfn looks_like_zip(data: &[u8]) -> bool {\n    data.len() > 4 && &data[..2] == b\"PK\" && data.len() > 1024 // avoid HTML error pages\n}\nif !looks_like_zip(&data) {\n    eprintln!(\"downloaded aria2c payload is not a zip; check proxy/network\");\n}","typeGuard":"fn is_zip_payload(data: &[u8]) -> bool {\n    data.len() >= 4 && data.starts_with(b\"PK\\x03\\x04\")\n}","tryCatchPattern":"match ensure_aria2c().await {\n    Some(path) => use_aria2c(path),\n    None => eprintln!(\"aria2c unavailable: zip open failed; check network/proxy and retry\"),\n}","preventionTips":["Validate the PK zip magic bytes and minimum size before parsing the archive","Apply a checksum (SHA-256) comparison against the official release before extraction","Set a reasonable timeout and check Content-Length matches the received body","Keep fallback logic: ensure_aria2c already returns Option — handle None gracefully","Log response status and body prefix on failure to detect HTML-from-proxy responses"],"tags":["rust","zip","download","corrupt-archive"],"backgroundTag":"file-open-failed","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}