{"record":{"id":"604a8149a3566bdf","repo":"tauri-apps/tauri","slug":"path-has-no-file-name","errorCode":null,"errorMessage":"Path has no file_name","messagePattern":"Path has no file_name","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tauri-bundler/src/bundle/updater_bundle.rs","lineNumber":249,"sourceCode":"fn create_tar(src_dir: &Path, dest_path: &Path) -> crate::Result<PathBuf> {\n  use flate2::{write::GzEncoder, Compression};\n\n  let dest_file = fs_utils::create_file(dest_path)?;\n  let gzip_encoder = GzEncoder::new(dest_file, Compression::default());\n\n  let gzip_encoder = create_tar_from_src(src_dir, gzip_encoder)?;\n\n  let mut dest_file = gzip_encoder.finish()?;\n  dest_file.flush()?;\n  Ok(dest_path.to_owned())\n}\n\n#[cfg(target_os = \"macos\")]\nfn create_tar_from_src<P: AsRef<Path>, W: Write>(src_dir: P, dest_file: W) -> crate::Result<W> {\n  let src_dir = src_dir.as_ref();\n  let mut builder = tar::Builder::new(dest_file);\n  builder.follow_symlinks(false);\n  builder.append_dir_all(src_dir.file_name().expect(\"Path has no file_name\"), src_dir)?;\n  builder.into_inner().map_err(Into::into)\n}\n\n#[cfg(target_os = \"linux\")]\nfn create_tar_from_src<P: AsRef<Path>, W: Write>(src_dir: P, dest_file: W) -> crate::Result<W> {\n  let src_dir = src_dir.as_ref();\n  let mut tar_builder = tar::Builder::new(dest_file);\n\n  // validate source type\n  let file_type = fs::metadata(src_dir).expect(\"Can't read source directory\");\n  // if it's a file don't need to walkdir\n  if file_type.is_file() {\n    let mut src_file = fs::File::open(src_dir)?;\n    let file_name = src_dir\n      .file_name()\n      .expect(\"Can't extract file name from path\");\n\n    tar_builder.append_file(file_name, &mut src_file)?;","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/tauri-apps/tauri/blob/52e4b6e71d8632a7e648f866c442e287ecddee34/crates/tauri-bundler/src/bundle/updater_bundle.rs#L231-L267","documentation":"On macOS the updater tar is created with append_dir_all under the .app directory's file_name. src_dir.file_name() is None only when the .app bundle path is a root or ends with '..', so this is an invariant on the computed bundle path rather than a config check.","triggerScenarios":"tauri build with createUpdaterArtifacts where the computed path to the .app ends without a file-name component — e.g. productName resolving to '..'-like values; not hit with normal configurations.","commonSituations":"Edge-case configs or custom path overrides; effectively unreachable for stock projects.","solutions":["Re-run from a clean target with default bundle settings","Verify productName in tauri.conf.json is a normal, non-empty, path-safe name","Report upstream with the config if reproducible"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// before updater bundling, the .app path must keep a file-name component\nlet app = std::path::Path::new(\"target/release/bundle/macos/MyApp.app\");\nif app.file_name().is_none() { anyhow::bail!(\"computed .app path has no file name: {}\", app.display()); }","typeGuard":"const isSafeName = (s) => typeof s === 'string' && s.length > 0 && !s.includes('/') && !s.includes('..');","tryCatchPattern":null,"preventionTips":["Keep productName a normal non-empty, path-safe value","Avoid custom tooling that rewrites bundle output paths after the bundler computes them"],"tags":["updater","macos","tar","invariant","tauri-bundler"],"backgroundTag":"invalid-path","analyzedSha":"52e4b6e71d8632a7e648f866c442e287ecddee34","analyzedAt":"2026-08-20T13:59:20.734Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}