{"record":{"id":"016affd58bcff38e","repo":"jdx/mise","slug":"extract-archive-does-not-support-compressed-single","errorCode":null,"errorMessage":"extract_archive does not support compressed single-file format: {format}","messagePattern":"extract_archive does not support compressed single-file format: (.+?)","errorType":"exception","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/file.rs","lineNumber":1935,"sourceCode":"        ExtractionFormat::TarGz\n        | ExtractionFormat::TarXz\n        | ExtractionFormat::TarBz2\n        | ExtractionFormat::TarZst\n        | ExtractionFormat::Tar\n        | ExtractionFormat::TarBr\n        | ExtractionFormat::TarLz4\n        | ExtractionFormat::TarSz\n        | ExtractionFormat::Raw => untar(archive, dest, format, opts),\n        ExtractionFormat::Zip => unzip(archive, dest, opts),\n        ExtractionFormat::SevenZip => un7z(archive, dest, opts),\n        ExtractionFormat::Gz\n        | ExtractionFormat::Xz\n        | ExtractionFormat::Bz2\n        | ExtractionFormat::Zst\n        | ExtractionFormat::Br\n        | ExtractionFormat::Lz4\n        | ExtractionFormat::Sz => {\n            bail!(\"extract_archive does not support compressed single-file format: {format}\")\n        }\n        ExtractionFormat::Rar => bail!(\"rar format not supported\"),\n    }\n}\n\npub fn untar(\n    archive: &Path,\n    dest: &Path,\n    format: ExtractionFormat,\n    opts: &ExtractOptions,\n) -> Result<()> {\n    if !format.is_tar_archive() && format != ExtractionFormat::Raw {\n        bail!(\"untar only supports tar formats, got {}\", format);\n    }\n\n    debug!(\"tar -xf {} -C {}\", archive.display(), dest.display());\n    if let Some(pr) = &opts.pr {\n        pr.set_message(format!(","sourceCodeStart":1917,"sourceCodeEnd":1953,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/file.rs#L1917-L1953","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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","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","Pre-check the format before extracting: only call extract_archive for container formats (is_tar_archive(), Zip, SevenZip)","For mise tool installs, fix the tool's backend/auba registry entry so asset patterns stop matching bare compressed files"],"exampleFix":"// before\nlet format = ExtractionFormat::from_path(&archive)?; // .gz -> ExtractionFormat::Gz\nfile::extract_archive(&archive, &dest, format, &opts)?; // bails: single-file format\n\n// after\nlet format = ExtractionFormat::from_path(&archive)?;\nif matches!(format, ExtractionFormat::Gz | ExtractionFormat::Xz | ExtractionFormat::Bz2\n    | ExtractionFormat::Zst | ExtractionFormat::Br | ExtractionFormat::Lz4 | ExtractionFormat::Sz) {\n    // single-file asset: decompress, do not extract\n    let mut reader = flate2::read::GzDecoder::new(std::fs::File::open(&archive)?);\n    let mut out = std::fs::File::create(dest.join(&bin_name))?;\n    std::io::copy(&mut reader, &mut out)?;\n} else {\n    file::extract_archive(&archive, &dest, format, &opts)?;\n}","handlingStrategy":"validation","validationCode":"let format = ExtractionFormat::from_path(&archive)?;\nlet is_container = format.is_tar_archive()\n    || matches!(format, ExtractionFormat::Zip | ExtractionFormat::SevenZip);\nif !is_container {\n    // single-file asset: decompress to a file, do not call extract_archive\n    decompress_single_file(&archive, &dest, format)?;\n} else {\n    file::extract_archive(&archive, &dest, format, &opts)?;\n}","typeGuard":"fn is_extractable_archive(f: ExtractionFormat) -> bool {\n    f.is_tar_archive() || matches!(f, ExtractionFormat::Zip | ExtractionFormat::SevenZip)\n}","tryCatchPattern":null,"preventionTips":["Treat bare .gz/.xz/.zst/.br/.lz4/.sz assets as single files to decompress, never as archives to extract","Derive ExtractionFormat from the full asset name so .tar.gz resolves to TarGz rather than Gz","Prefer .tar.gz or .zip release assets in backend/aqua config whenever the release offers them"],"tags":["archive","extraction","compression","rust","mise"],"backgroundTag":"unsupported-archive-format","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}