{"record":{"id":"4b8b838247636660","repo":"rust-lang/rust","slug":"couldn-t-figure-out-the-format-of","errorCode":null,"errorMessage":"couldn't figure out the format of {}","messagePattern":"couldn't figure out the format of (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/tools/rust-installer/src/combiner.rs","lineNumber":84,"sourceCode":"impl Combiner {\n    /// Combines the installer tarballs.\n    pub fn run(self) -> Result<()> {\n        create_dir_all(&self.work_dir)?;\n\n        let package_dir = Path::new(&self.work_dir).join(&self.package_name);\n        if package_dir.exists() {\n            remove_dir_all(&package_dir)?;\n        }\n        create_dir_all(&package_dir)?;\n\n        // Merge each installer into the work directory of the new installer.\n        let components = create_new_file(package_dir.join(\"components\"))?;\n        for input_tarball in self.input_tarballs.split(',').map(str::trim).filter(|s| !s.is_empty())\n        {\n            // Extract the input tarballs\n            let compression =\n                CompressionFormat::detect_from_path(input_tarball).ok_or_else(|| {\n                    anyhow::anyhow!(\"couldn't figure out the format of {}\", input_tarball)\n                })?;\n            Archive::new(compression.decode(input_tarball)?).unpack(&self.work_dir).with_context(\n                || format!(\"unable to extract '{}' into '{}'\", &input_tarball, self.work_dir),\n            )?;\n\n            let pkg_name =\n                input_tarball.trim_end_matches(&format!(\".tar.{}\", compression.extension()));\n            let pkg_name = Path::new(pkg_name).file_name().unwrap();\n            let pkg_dir = Path::new(&self.work_dir).join(pkg_name);\n\n            // Verify the version number.\n            let mut version = String::new();\n            open_file(pkg_dir.join(\"rust-installer-version\"))\n                .and_then(|mut file| Ok(file.read_to_string(&mut version)?))\n                .with_context(|| format!(\"failed to read version in '{}'\", input_tarball))?;\n            if version.trim().parse() != Ok(crate::RUST_INSTALLER_VERSION) {\n                bail!(\"incorrect installer version in {}\", input_tarball);\n            }","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/rust-lang/rust/blob/7088e4b63a9516ebfbfe2ab2d999cf01a528ac14/src/tools/rust-installer/src/combiner.rs#L66-L102","documentation":"Thrown by the rust-installer Combiner::run method when detecting the compression format of an input tarball. CompressionFormat::detect_from_path inspects the file extension and only recognizes .gz and .xz (compression.rs:54-59). Any other extension (or no extension) returns None, which becomes this anyhow error at combiner.rs:84.","triggerScenarios":"Passing --input-tarballs with a file whose extension is not .gz or .xz (e.g., package.tar.bz2, package.tar.zst, package.tar with no compression suffix, or a typo like package.tar.x). The Combiner splits the --input-tarballs value by comma and calls detect_from_path on each.","commonSituations":"Building Rust installers manually with rust-installer and pointing to a tarball compressed with an unsupported algorithm; switching tarball compression from gz/xz to zstd without updating the installer toolchain; typo in the file extension.","solutions":["Re-compress the input tarball using gzip (producing .tar.gz) or xz (producing .tar.xz) — these are the only supported formats.","Verify the file extension exactly matches .gz or .xz; check for typos like .xz vs .xs, or a missing dot.","If you need bz2/zst support, extend CompressionFormat::detect_from_path in compression.rs to recognize the new extension and add a matching decoder."],"exampleFix":"# before\n# recompress a bz2 tarball to xz\ntar xf package.tar.bz2 && tar cf - -C workdir package | xz -T6 > package.tar.xz\n# then pass the .tar.xz to --input-tarballs\n# after: --input-tarballs package.tar.xz","handlingStrategy":"validation","validationCode":"// Before passing a tarball path to the Combiner, verify its extension.\nuse std::path::Path;\n\nfn validate_tarball_extension(path: &str) -> Result<(), String> {\n    let p = Path::new(path);\n    let ext = p.extension().and_then(|e| e.to_str()).unwrap_or(\"\");\n    match ext {\n        \"gz\" | \"xz\" => Ok(()),\n        other => Err(format!(\"unsupported tarball extension '.{}': only .gz and .xz are supported\", other)),\n    }\n}","typeGuard":null,"tryCatchPattern":"// The Combiner returns anyhow::Result via Combiner::run().\nmatch combiner.run() {\n    Ok(()) => println!(\"installer created\"),\n    Err(e) => {\n        if e.to_string().contains(\"couldn't figure out the format\") {\n            eprintln!(\"Input tarball has an unsupported compression. Use .tar.gz or .tar.xz.\");\n        }\n        return Err(e);\n    }\n}","preventionTips":["Always produce input tarballs with .tar.gz or .tar.xz extensions.","Validate file extensions before invoking the Combiner.","Document the supported compression formats in your build scripts."],"tags":["rust-installer","compression","tarball","config"],"backgroundTag":null,"analyzedSha":"7088e4b63a9516ebfbfe2ab2d999cf01a528ac14","analyzedAt":"2026-08-10T14:17:03.603Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}