jdx/mise · error · eyre::Report

extract_archive does not support compressed single-file form

Error message

extract_archive does not support compressed single-file format: {format}

What it means

Thrown by mise's extract_archive (src/file.rs) when asked to extract a single-file compression format (Gz, Xz, Bz2, Zst, Br, Lz4, Sz). These codecs compress exactly one byte stream, not a collection of entries, so there is no directory structure to unpack into dest; the extraction API only handles container formats (tar variants, zip, 7z). Hitting it usually means format detection classified a bare compressed asset (e.g. tool-linux-amd64.gz) as an archive to extract.

Source

Thrown at src/file.rs:1935

        ExtractionFormat::TarGz
        | ExtractionFormat::TarXz
        | ExtractionFormat::TarBz2
        | ExtractionFormat::TarZst
        | ExtractionFormat::Tar
        | ExtractionFormat::TarBr
        | ExtractionFormat::TarLz4
        | ExtractionFormat::TarSz
        | ExtractionFormat::Raw => untar(archive, dest, format, opts),
        ExtractionFormat::Zip => unzip(archive, dest, opts),
        ExtractionFormat::SevenZip => un7z(archive, dest, opts),
        ExtractionFormat::Gz
        | ExtractionFormat::Xz
        | ExtractionFormat::Bz2
        | ExtractionFormat::Zst
        | ExtractionFormat::Br
        | ExtractionFormat::Lz4
        | ExtractionFormat::Sz => {
            bail!("extract_archive does not support compressed single-file format: {format}")
        }
        ExtractionFormat::Rar => bail!("rar format not supported"),
    }
}

pub fn untar(
    archive: &Path,
    dest: &Path,
    format: ExtractionFormat,
    opts: &ExtractOptions,
) -> Result<()> {
    if !format.is_tar_archive() && format != ExtractionFormat::Raw {
        bail!("untar only supports tar formats, got {}", format);
    }

    debug!("tar -xf {} -C {}", archive.display(), dest.display());
    if let Some(pr) = &opts.pr {
        pr.set_message(format!(

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. If the asset is a single compressed file, decompress it with the matching decoder (flate2 GzDecoder, xz2, zstd, brotli, lz4_flex) and write the result to dest as a file instead of calling extract_archive
  2. If the release also offers a container archive (.tar.gz, .tar.xz, .zip), point the backend/asset matcher at that variant so the format resolves to a tar or zip variant
  3. Pre-check the format before extracting: only call extract_archive for container formats (is_tar_archive(), Zip, SevenZip)
  4. For mise tool installs, fix the tool's backend/auba registry entry so asset patterns stop matching bare compressed files

Example fix

// before
let format = ExtractionFormat::from_path(&archive)?; // .gz -> ExtractionFormat::Gz
file::extract_archive(&archive, &dest, format, &opts)?; // bails: single-file format

// after
let format = ExtractionFormat::from_path(&archive)?;
if matches!(format, ExtractionFormat::Gz | ExtractionFormat::Xz | ExtractionFormat::Bz2
    | ExtractionFormat::Zst | ExtractionFormat::Br | ExtractionFormat::Lz4 | ExtractionFormat::Sz) {
    // single-file asset: decompress, do not extract
    let mut reader = flate2::read::GzDecoder::new(std::fs::File::open(&archive)?);
    let mut out = std::fs::File::create(dest.join(&bin_name))?;
    std::io::copy(&mut reader, &mut out)?;
} else {
    file::extract_archive(&archive, &dest, format, &opts)?;
}
Defensive patterns

Strategy: validation

Validate before calling

let format = ExtractionFormat::from_path(&archive)?;
let is_container = format.is_tar_archive()
    || matches!(format, ExtractionFormat::Zip | ExtractionFormat::SevenZip);
if !is_container {
    // single-file asset: decompress to a file, do not call extract_archive
    decompress_single_file(&archive, &dest, format)?;
} else {
    file::extract_archive(&archive, &dest, format, &opts)?;
}

Type guard

fn is_extractable_archive(f: ExtractionFormat) -> bool {
    f.is_tar_archive() || matches!(f, ExtractionFormat::Zip | ExtractionFormat::SevenZip)
}

Prevention

When it happens

Trigger: Calling file::extract_archive(archive, dest, format, opts) where format is ExtractionFormat::Gz/Xz/Bz2/Zst/Br/Lz4/Sz. Typically the format was inferred from a downloaded release asset's final extension, such as .gz, .xz, .zst, .br, .lz4, or .sz.

Common situations: A tool's release assets switch from .tar.gz to a raw compressed binary (common for Go/Rust single-binary projects); an aqua/mise backend or asset matcher picks the .gz/.xz variant; custom install code reuses extract_archive for every downloaded file regardless of type.

Related errors


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/016affd58bcff38e. Report an issue: GitHub.