{"record":{"id":"cb709cd22769f1b5","repo":"denoland/deno","slug":"unsupported-archive-type-ext","errorCode":null,"errorMessage":"Unsupported archive type: '{ext}'","messagePattern":"Unsupported archive type: '(.+?)'","errorType":"exception","errorClass":"AnyError","httpStatus":null,"severity":"error","filePath":"cli/util/archive.rs","lineNumber":112,"sourceCode":"  let archive_ext = Path::new(archive_name)\n    .extension()\n    .and_then(|ext| ext.to_str())\n    .unwrap();\n  match archive_ext {\n    \"zip\" => match unzip(archive_name, archive_data, dest_path) {\n      Ok(()) if !exe_path.exists() => {\n        log::warn!(\"unpacking via the zip crate didn't produce the executable\");\n        // No error but didn't produce exe, fallback to shelling out\n        unzip_with_shell(&archive_path, archive_data, dest_path)?;\n      }\n      Ok(_) => {}\n      Err(e) => {\n        log::warn!(\"unpacking via zip crate failed: {e}\");\n        // Fallback to shelling out\n        unzip_with_shell(&archive_path, archive_data, dest_path)?;\n      }\n    },\n    ext => bail!(\"Unsupported archive type: '{ext}'\"),\n  }\n\n  assert!(exe_path.exists());\n  Ok(exe_path)\n}\n\n#[cfg(test)]\nmod tests {\n  use std::io::Write;\n\n  use super::*;\n\n  fn make_zip(file_name: &str, contents: &[u8]) -> Vec<u8> {\n    let mut buf = Vec::new();\n    let mut writer = zip::ZipWriter::new(std::io::Cursor::new(&mut buf));\n    writer\n      .start_file(file_name, zip::write::SimpleFileOptions::default())\n      .unwrap();","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/cli/util/archive.rs#L94-L130","documentation":"`unpack_into_dir` dispatches solely on the extension of `archive_name` and implements only the `zip` arm; every other extension is rejected before any bytes are read. Because Deno's own release artifacts are zips, end users should rarely see this — it usually means a custom feed or API caller supplied a tar/tar.gz/7z artifact where a zip was expected.","triggerScenarios":"Calling `unpack_into_dir` (directly, or via Deno install/upgrade machinery pointed at a custom source) with an `archive_name` whose extension is not exactly `zip` — e.g. `deno.tar.gz`, `deno.tgz`, or an artifact whose filename lost its extension.","commonSituations":"Custom upgrade feeds or mirrors serving .tar.gz instead of .zip; test fixtures with misnamed archives; a download URL that redirects to an error page whose 'filename' has a different extension.","solutions":["Re-package or fetch the artifact as a .zip (Deno publishes zips for its binaries).","If scripting against the API, assert the extension is `zip` before calling `unpack_into_dir`.","If a zip was expected, inspect the actual download URL/response — a proxy or redirect may be serving something else under a different filename."],"exampleFix":"// before\nlet exe = unpack_into_dir(UnpackArgs { archive_name: \"deno.tar.gz\", ..args })?;\n\n// after: only the zip arm exists\nlet exe = unpack_into_dir(UnpackArgs { archive_name: \"deno.zip\", ..args })?;","handlingStrategy":"validation","validationCode":"// reject unsupported archives before calling unpack_into_dir\nlet ext = std::path::Path::new(archive_name)\n  .extension()\n  .and_then(|e| e.to_str());\nif ext != Some(\"zip\") {\n  return Err(anyhow::anyhow!(\"only .zip archives are supported\"));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Assert the artifact extension is zip before invoking download/unpack helpers.","Serve and consume release artifacts in one canonical format (zip).","Log the served Content-Disposition/filename when behind proxies so format mismatches are visible."],"tags":["archive","unsupported-format","zip"],"backgroundTag":"unsupported-archive-format","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}