tonhowtf/omniget · error · anyhow::Error

Failed to open archive

Error message

Failed to open archive: {}

What it means

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.

Solutions

  1. Verify the archive file exists at the logged path before extraction (ls / stat)
  2. Exclude the app's temp/bin directory from antivirus real-time scanning
  3. Avoid concurrent downloads/extractions into the same bin_dir (add a lock or dedupe in-flight calls)
  4. Check file permissions on the temp file and parent directory
  5. Retry the download to regenerate the archive
Defensive patterns

Strategy: validation

Validate before calling

if !archive_path.exists() {
    eprintln!("archive missing before extraction; re-download required");
}

Try / catch

match download_ffmpeg().await {
    Ok(p) => ...,
    Err(e) if e.to_string().contains("Failed to open archive") => {
        eprintln!("archive vanished/unreadable — re-downloading");
        re_download_and_install().await;
    }
    Err(e) => ...,
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


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

Appendix: source

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

            ArchiveType::TarXz,
        )]
    }
}

async fn extract_zip_ffmpeg(
    archive_path: &std::path::Path,
    bin_dir: &std::path::Path,
    ffmpeg_name: &str,
    ffprobe_name: &str,
) -> anyhow::Result<()> {
    let archive_path = archive_path.to_path_buf();
    let bin_dir = bin_dir.to_path_buf();
    let ffmpeg_name = ffmpeg_name.to_string();
    let ffprobe_name = ffprobe_name.to_string();

    tokio::task::spawn_blocking(move || {
        let file = std::fs::File::open(&archive_path)
            .map_err(|e| anyhow!("Failed to open archive: {}", e))?;
        let mut archive =
            zip::ZipArchive::new(file).map_err(|e| anyhow!("Failed to open zip: {}", e))?;

        let targets = [ffmpeg_name.as_str(), ffprobe_name.as_str()];

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

            let name = entry.name().to_string();
            for target in &targets {
                if name.ends_with(target) {
                    let dest = bin_dir.join(format!("{}.new", target));
                    let mut out = std::fs::File::create(&dest)?;
                    std::io::copy(&mut entry, &mut out)?;
                    break;
                }

View on GitHub (pinned to 8600b91f42)