tauri-apps/tauri · error

Path has no file_name

Error message

Path has no file_name

What it means

Panic from `.expect("Path has no file_name")` in the macOS `create_tar_from_src`. The function appends the source directory itself into the tar via `append_dir_all(src_dir.file_name()..., src_dir)`, so it needs the directory's final path component as the archive entry name. `file_name()` returns `None` when the path is a root, ends in `..`, or is empty, and the bundler panics rather than emitting a partial archive.

Solutions

  1. Canonicalize `src_dir` before calling so `..` components are resolved (`std::fs::canonicalize`)
  2. Pass the actual `.app`/directory path (with a real final component) as the source, not a parent or root path
  3. Avoid building the directory path with `join("..")`; keep a direct path to the bundle directory
  4. Pre-validate in calling code: `assert!(src_dir.file_name().is_some())` or return an explicit error

Example fix

// before
let dir = cfg_out.join("..").join("myapp.app");
create_tar(dir, dest)?; // panics if join("..") is last component
// after
let dir = cfg_out.join("..").join("myapp.app").canonicalize()?;
create_tar(dir, dest)?;
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_dir_with_name(p: &std::path::Path) -> Result<(), String> {
    if !p.is_dir() {
        return Err(format!("not a directory: {}", p.display()));
    }
    if p.file_name().is_none() {
        return Err(format!("directory path has no final component: {}", p.display()));
    }
    Ok(())
}
// call before create_tar on macOS

Type guard

fn has_file_name(p: &std::path::Path) -> bool {
    p.file_name().is_some()
}

Prevention

When it happens

Trigger: Calling `create_tar`/`create_tar_from_src` on macOS with a `src_dir` that is `/`, a drive/volume root, ends in `..`, or otherwise has no last component. Reached during macOS updater bundle generation.

Common situations: Passing a volume root (e.g. `/Volumes/`) or a path with `..` as the app bundle directory, misconfigured `bundle` output paths in tauri.conf.json, or paths built by repeated `pop()`/`join("..")` calls that reduced the path past its last component.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of tauri-apps/tauri@460ec35447 (2026-09-18). Data as JSON: /api/errors/604a8149a3566bdf. Report an issue: GitHub.

Appendix: source

Thrown at crates/tauri-bundler/src/bundle/updater_bundle.rs:249

fn create_tar(src_dir: &Path, dest_path: &Path) -> crate::Result<PathBuf> {
  use flate2::{Compression, write::GzEncoder};

  let dest_file = fs_utils::create_file(dest_path)?;
  let gzip_encoder = GzEncoder::new(dest_file, Compression::default());

  let gzip_encoder = create_tar_from_src(src_dir, gzip_encoder)?;

  let mut dest_file = gzip_encoder.finish()?;
  dest_file.flush()?;
  Ok(dest_path.to_owned())
}

#[cfg(target_os = "macos")]
fn create_tar_from_src<P: AsRef<Path>, W: Write>(src_dir: P, dest_file: W) -> crate::Result<W> {
  let src_dir = src_dir.as_ref();
  let mut builder = tar::Builder::new(dest_file);
  builder.follow_symlinks(false);
  builder.append_dir_all(src_dir.file_name().expect("Path has no file_name"), src_dir)?;
  builder.into_inner().map_err(Into::into)
}

#[cfg(target_os = "linux")]
fn create_tar_from_src<P: AsRef<Path>, W: Write>(src_dir: P, dest_file: W) -> crate::Result<W> {
  let src_dir = src_dir.as_ref();
  let mut tar_builder = tar::Builder::new(dest_file);

  // validate source type
  let file_type = fs::metadata(src_dir).expect("Can't read source directory");
  // if it's a file don't need to walkdir
  if file_type.is_file() {
    let mut src_file = fs::File::open(src_dir)?;
    let file_name = src_dir
      .file_name()
      .expect("Can't extract file name from path");

    tar_builder.append_file(file_name, &mut src_file)?;

View on GitHub (pinned to 460ec35447)