{"record":{"id":"ee9d03928b4ce584","repo":"tonhowtf/omniget","slug":"failed-to-read-zip-entry","errorCode":null,"errorMessage":"Failed to read zip entry: {}","messagePattern":"Failed to read zip entry: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/dependencies.rs","lineNumber":593,"sourceCode":"    ffprobe_name: &str,\n) -> anyhow::Result<()> {\n    let archive_path = archive_path.to_path_buf();\n    let bin_dir = bin_dir.to_path_buf();\n    let ffmpeg_name = ffmpeg_name.to_string();\n    let ffprobe_name = ffprobe_name.to_string();\n\n    tokio::task::spawn_blocking(move || {\n        let file = std::fs::File::open(&archive_path)\n            .map_err(|e| anyhow!(\"Failed to open archive: {}\", e))?;\n        let mut archive =\n            zip::ZipArchive::new(file).map_err(|e| anyhow!(\"Failed to open zip: {}\", e))?;\n\n        let targets = [ffmpeg_name.as_str(), ffprobe_name.as_str()];\n\n        for i in 0..archive.len() {\n            let mut entry = archive\n                .by_index(i)\n                .map_err(|e| anyhow!(\"Failed to read zip entry: {}\", e))?;\n\n            let name = entry.name().to_string();\n            for target in &targets {\n                if name.ends_with(target) {\n                    let dest = bin_dir.join(format!(\"{}.new\", target));\n                    let mut out = std::fs::File::create(&dest)?;\n                    std::io::copy(&mut entry, &mut out)?;\n                    break;\n                }\n            }\n        }\n\n        Ok::<(), anyhow::Error>(())\n    })\n    .await\n    .map_err(|e| anyhow!(\"Spawn blocking failed: {}\", e))??;\n\n    Ok(())","sourceCodeStart":575,"sourceCodeEnd":611,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/dependencies.rs#L575-L611","documentation":"In extract_zip_ffmpeg, each entry of the downloaded FFmpeg zip archive is opened with archive.by_index(i) inside a spawn_blocking task. If the zip central/local directory entry cannot be read or decoded, the zip crate error is wrapped with anyhow into this message and propagated as an anyhow::Error through download_ffmpeg.","triggerScenarios":"Calling download_ffmpeg on a truncated, corrupt, or non-zip file whose outer reads still let by_index be attempted; zip entries with unsupported compression methods or bad local headers; I/O errors while seeking within the archive file.","commonSituations":"Interrupted/partial download of the FFmpeg zip; proxy or CDN serving an HTML error page saved as .zip; disk issues or antivirus locking the file mid-read; a URL change upstream now points at a different archive format.","solutions":["Delete the cached archive and re-run download_ffmpeg to get a fresh copy","Verify the download URL returns a real zip (check Content-Type / magic bytes 'PK') before extraction","Confirm the zip crate version supports the archive's compression method (e.g. bzip2/deflate64 features)","Check disk space and that no other process holds the archive file open"],"exampleFix":"// before\nlet mut entry = archive\n    .by_index(i)\n    .map_err(|e| anyhow!(\"Failed to read zip entry: {}\", e))?;\n// after\nlet mut entry = archive\n    .by_index(i)\n    .map_err(|e| anyhow!(\"Failed to read zip entry {} (archive may be corrupt or incomplete; re-download): {}\", i, e))?;","handlingStrategy":"try-catch","validationCode":"let meta = std::fs::metadata(&archive_path)?;\nif meta.len() < 1024 { return Err(anyhow!(\"Archive too small to be a valid zip\")); }\nlet mut f = std::fs::File::open(&archive_path)?;\nlet mut magic = [0u8; 4];\nstd::io::Read::read_exact(&mut f, &mut magic)?;\nif &magic != b\"PK\\x03\\x04\" { return Err(anyhow!(\"Not a zip file; re-download\")); }","typeGuard":"fn looks_like_zip(bytes: &[u8]) -> bool { bytes.starts_with(b\"PK\\x03\\x04\") || bytes.starts_with(b\"PK\\x05\\x06\") }","tryCatchPattern":"match extract_zip_ffmpeg(&path, &bin_dir, &ffmpeg, &ffprobe).await {\n    Ok(()) => {},\n    Err(e) if e.to_string().contains(\"Failed to read zip entry\") => {\n        std::fs::remove_file(&path).ok();\n        // re-download then retry once\n    },\n    Err(e) => return Err(e),\n}","preventionTips":["Verify download size and zip magic bytes before extraction","Re-download instead of reusing cached archives after any failed install","Pin/verify a checksum of the archive when possible","Keep the zip crate updated for newer compression methods"],"tags":["zip","archive-extraction","corrupt-file"],"backgroundTag":"file-read-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"}