{"record":{"id":"e4f8245d02ee31a3","repo":"tauri-apps/tauri","slug":"failed-to-get-parent","errorCode":null,"errorMessage":"Failed to get parent","messagePattern":"Failed to get parent","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tauri-bundler/src/utils/http_utils.rs","lineNumber":172,"sourceCode":"\n/// Extracts the zips from memory into a usable path.\n#[allow(dead_code)]\npub fn extract_zip(data: &[u8], path: &Path) -> crate::Result<()> {\n  let cursor = Cursor::new(data);\n\n  let mut zipa = ZipArchive::new(cursor)?;\n\n  for i in 0..zipa.len() {\n    let mut file = zipa.by_index(i)?;\n\n    if let Some(name) = file.enclosed_name() {\n      let dest_path = path.join(name);\n      if file.is_dir() {\n        create_dir_all(&dest_path)?;\n        continue;\n      }\n\n      let parent = dest_path.parent().expect(\"Failed to get parent\");\n\n      if !parent.exists() {\n        create_dir_all(parent)?;\n      }\n\n      let mut buff: Vec<u8> = Vec::new();\n      file.read_to_end(&mut buff)?;\n      let mut fileout = File::create(dest_path).expect(\"Failed to open file\");\n\n      fileout.write_all(&buff)?;\n    }\n  }\n\n  Ok(())\n}\n\n#[cfg(test)]\nmod tests {","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/tauri-apps/tauri/blob/460ec35447493200d64290dd7f015d5a91d0fd58/crates/tauri-bundler/src/utils/http_utils.rs#L154-L190","documentation":"http_utils::extract_zip unzips a downloaded archive (used for the WiX toolset). For each non-directory entry it computes dest_path.parent() and .expect()s it; an entry whose name has no directory component (a top-level file like 'LICENSE' extracted to path.join(name)) makes parent() return None, panicking with 'Failed to get parent'.","triggerScenarios":"get_and_extract_wix -> extract_zip when the zip archive contains a top-level file entry (no folder prefix in its name) so dest_path = path.join(name) still has no parent? — specifically when `path` itself is empty/root, making dest_path.parent() None.","commonSituations":"WiX toolset download URL changed and a differently-structured archive (files at zip root instead of inside a folder) is extracted; corrupted or partially downloaded zip; proxy/mirror serving unexpected content; cache poisoning under %LOCALAPPDATA%.","solutions":["Clear the cached WiX toolset directory (e.g. %LOCALAPPDATA%/tauri/WixTools) and let tauri re-download it.","Update tauri-cli / tauri-bundler so the bundled WiX URL matches the current archive layout.","Check network setup (proxy/mirror) that could serve a modified zip, and retry the download.","Verify the downloaded zip integrity (open it manually and confirm entries are inside a folder)."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// Verify the downloaded WiX zip has a sane layout before extraction\nlet f = std::fs::File::open(&zip_path)?;\nlet mut z = zip::ZipArchive::new(f)?;\nassert!(z.file_names().any(|n| n.contains('/')), \"unexpected WiX archive layout: entries at zip root\");","typeGuard":null,"tryCatchPattern":"// Wrap get_and_extract_wix; on panic-free failure, wipe the cache and retry once\nmatch get_and_extract_wix(&dest) {\n  Ok(_) => {},\n  Err(e) => {\n    let _ = std::fs::remove_dir_all(&dest);\n    get_and_extract_wix(&dest).expect(\"WiX toolset download failed twice\");\n  }\n}","preventionTips":["Clear the WixTools cache after tauri-cli upgrades.","Avoid proxies/mirrors that can alter downloaded archives.","Pin tauri-cli versions so the WiX URL and extraction logic stay consistent."],"tags":["zip","filesystem","path","windows","wix"],"backgroundTag":"internal-invariant-violation","analyzedSha":"460ec35447493200d64290dd7f015d5a91d0fd58","analyzedAt":"2026-09-18T23:55:51.277Z","contentChangedAt":"2026-09-18T23:55:51.277Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}