tonhowtf/omniget · error

tar.xz invalido: {}

Error message

tar.xz invalido: {}

What it means

Extraction failure wrapper in the GitHub asset unpacker: when the downloaded asset name ends with .tar.gz or .tgz, the archive is decoded with GzDecoder and unpacked into dest; if tar::Archive::unpack fails (corrupt gzip stream, malformed tar member, I/O error writing into dest, permission problem), the raw error is remapped to this message with the underlying error in {}. It fires only for the tar.gz/tgz branch of unpack — a bad or truncated archive or an unwritable destination.

Solutions

  1. Re-download and verify the digest before unpacking
  2. Confirm the payload starts with xz magic (FD 37 7A 58 5A 00)
  3. If the project actually ships .tar.gz, unpack with the matching name instead
Defensive patterns

Strategy: validation

Validate before calling

fn looks_like_xz(data: &[u8]) -> bool {
    data.starts_with(&[0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00])
}
if !looks_like_xz(&data) {
    return Err("payload nao e xz; confira o nome e o conteudo do asset".into());
}
github::unpack(&data, name, &dest)?;

Try / catch

match github::unpack(&data, name, &dest) {
    Err(e) if e.to_string().starts_with("tar.xz invalido") => {
        eprintln!("download corrompido ou nome errado; refazendo...");
        let data = github::download(&asset).await?;
        github::unpack(&data, name, &dest)?;
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling unpack() with a .tar.xz name whose bytes fail xz decompression or tar extraction: truncated stream, corrupt xz frame, or non-xz payload.

Common situations: Interrupted downloads of large xz archives; release asset replaced/re-compressed between download and unpack; mislabeled payload that is actually .tar.gz.

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

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/github.rs:148

            }
            let mut w = std::fs::File::create(&out)?;
            std::io::copy(&mut file, &mut w)?;
        }
        Ok(())
    } else if name.ends_with(".tar.gz") || name.ends_with(".tgz") {
        let decoder = flate2::read::GzDecoder::new(std::io::Cursor::new(data));
        let mut archive = tar::Archive::new(decoder);
        archive.set_preserve_permissions(true);
        archive
            .unpack(dest)
            .map_err(|e| anyhow!("tar.gz invalido: {}", e))
    } else if name.ends_with(".tar.xz") {
        let decoder = xz2::read::XzDecoder::new(std::io::Cursor::new(data));
        let mut archive = tar::Archive::new(decoder);
        archive.set_preserve_permissions(true);
        archive
            .unpack(dest)
            .map_err(|e| anyhow!("tar.xz invalido: {}", e))
    } else {
        Err(anyhow!("formato de pacote desconhecido: {}", name))
    }
}

/// Procura um arquivo pelo nome dentro de uma árvore (os zips do whisper.cpp
/// e do Real-ESRGAN têm subpastas diferentes por plataforma).
pub fn find_file(root: &Path, file_name: &str) -> Option<PathBuf> {
    let mut stack = vec![root.to_path_buf()];
    while let Some(dir) = stack.pop() {
        let Ok(rd) = std::fs::read_dir(&dir) else {
            continue;
        };
        for entry in rd.flatten() {
            let p = entry.path();
            if p.is_dir() {
                stack.push(p);
            } else if p.file_name().map(|n| n == file_name).unwrap_or(false) {

View on GitHub (pinned to 8600b91f42)