{"record":{"id":"9a92bfe0ce35d280","repo":"tonhowtf/omniget","slug":"failed-to-open-archive","errorCode":null,"errorMessage":"Failed to open archive: {}","messagePattern":"Failed to open archive: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/dependencies.rs","lineNumber":584,"sourceCode":"            ArchiveType::TarXz,\n        )]\n    }\n}\n\nasync fn extract_zip_ffmpeg(\n    archive_path: &std::path::Path,\n    bin_dir: &std::path::Path,\n    ffmpeg_name: &str,\n    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                }","sourceCodeStart":566,"sourceCodeEnd":602,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/dependencies.rs#L566-L602","documentation":"extract_zip_ffmpeg() opens the downloaded archive file with std::fs::File::open inside spawn_blocking. If the file cannot be opened (missing, permission denied, or deleted before extraction), the OS error is wrapped in this anyhow error and extraction aborts.","triggerScenarios":"The temp archive file at archive_path does not exist or is unreadable when extraction starts — deleted by antivirus/cleanup, written to a path without read permission, or raced by a concurrent cleanup.","commonSituations":"Antivirus removing the .tmp download before extraction; another ensure_ffmpeg run deleting the temp file concurrently; running without permission to read the bin_dir temp file; disk issues.","solutions":["Verify the archive file exists at the logged path before extraction (ls / stat)","Exclude the app's temp/bin directory from antivirus real-time scanning","Avoid concurrent downloads/extractions into the same bin_dir (add a lock or dedupe in-flight calls)","Check file permissions on the temp file and parent directory","Retry the download to regenerate the archive"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if !archive_path.exists() {\n    eprintln!(\"archive missing before extraction; re-download required\");\n}","typeGuard":null,"tryCatchPattern":"match download_ffmpeg().await {\n    Ok(p) => ...,\n    Err(e) if e.to_string().contains(\"Failed to open archive\") => {\n        eprintln!(\"archive vanished/unreadable — re-downloading\");\n        re_download_and_install().await;\n    }\n    Err(e) => ...,\n}","preventionTips":["Serialize installs with a mutex/lock to prevent temp-file races","Whitelist the temp/bin directory in antivirus software","Keep the archive open/locked until extraction completes","Check permissions on the temp directory before downloading"],"tags":["filesystem","rust","archive","permissions"],"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"}