tonhowtf/omniget · error · anyhow::Error

Failed to read tar entry

Error message

Failed to read tar entry: {}

What it means

While iterating tar entries in extract_tar_xz_ffmpeg, each individual entry_result is unwrapped; a per-entry error (I/O read failure while advancing the stream, malformed header for that member) is wrapped as 'Failed to read tar entry'. entries() yields Err for the bad member and iteration then stops.

Solutions

  1. Re-download the archive and retry extraction
  2. Validate the archive with an external tool (xz -t file.tar.xz; tar -tf) to confirm corruption
  3. Log which entry index failed to identify the corruption point
  4. Verify available disk space; ENOSPC surfaces as read/write errors during iteration

Example fix

// before
let mut entry = entry_result.map_err(|e| anyhow!("Failed to read tar entry: {}", e))?;
// after
let mut entry = entry_result.map_err(|e| anyhow!("Failed to read tar entry (archive likely truncated/corrupt, re-download): {}", e))?;
Defensive patterns

Strategy: try-catch

Try / catch

// validate archive integrity beforehand with xz2 streaming decode
match extract_tar_xz_ffmpeg(&path, &bin, &ff, &fprobe).await {
    Err(e) if e.to_string().contains("Failed to read tar entry") => {
        eprintln!("archive corrupt mid-stream, re-downloading");
        std::fs::remove_file(&path).ok();
        // re-download and retry once
    },
    r => r?,
}

Prevention

When it happens

Trigger: Corrupt or truncated xz/tar stream hit at a specific member boundary; unreadable data block; a member header with invalid checksum or encoding that the tar crate rejects.

Common situations: Partial download where the tail of the archive is cut off; disk read errors; archives produced by tools emitting nonstandard headers the tar crate refuses.

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/b0d93968b75deea0. Report an issue: GitHub.

Appendix: source

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

    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 decompressor = xz2::read::XzDecoder::new(file);
        let mut archive = tar::Archive::new(decompressor);
        let targets = [ffmpeg_name.as_str(), ffprobe_name.as_str()];

        for entry_result in archive
            .entries()
            .map_err(|e| anyhow!("Failed to read tar entries: {}", e))?
        {
            let mut entry = entry_result.map_err(|e| anyhow!("Failed to read tar entry: {}", e))?;
            let path = entry
                .path()
                .map_err(|e| anyhow!("Failed to read entry path: {}", e))?;
            let file_name = path.file_name().and_then(|n| n.to_str()).unwrap_or("");
            for target in &targets {
                if file_name == *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;
                }
            }
        }
        Ok::<(), anyhow::Error>(())
    })
    .await
    .map_err(|e| anyhow!("Spawn blocking failed: {}", e))??;
    Ok(())

View on GitHub (pinned to 8600b91f42)