tauri-apps/tauri · critical

Couldn't get framework filename

Error message

Couldn't get framework filename

What it means

In tauri-build's copy_frameworks, each entry ending in `.framework` is treated as a macOS framework bundle directory; the code calls `Path::file_name()` and expects a name to compute the destination path. When the framework path has no final component (trailing slash, `..`, root), file_name() returns None and the expect panics. It indicates a malformed framework path in the build configuration.

Solutions

  1. Remove trailing slashes / `..` components from the framework path so it ends in `Name.framework`.
  2. Verify the framework path in tauri.conf.json points at the bundle directory itself, not its parent.
  3. If the path comes from an env var or script, print it during build to confirm it is non-empty and well-formed.
  4. Pre-resolve the path (canonicalize) and assert `path.file_name().is_some()` before configuring the build.

Example fix

// before
"frameworks": ["libs/MyKit.framework/"]
// after
"frameworks": ["libs/MyKit.framework"]
Defensive patterns

Strategy: validation

Validate before calling

for fw in frameworks {
  let p = std::path::Path::new(fw);
  assert!(fw.ends_with(".framework") && !fw.ends_with('/'), "malformed framework path: {fw}");
  assert!(p.file_name().is_some(), "no filename in framework path: {fw}");
}

Type guard

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

Prevention

When it happens

Trigger: tauri_build::try_build with Attributes::copy_frameworks containing a `.framework` path lacking a filename component, e.g. `"../"`-relative or trailing-slash paths.

Common situations: A tauri.conf.json `bundle.macOS.frameworks` entry written as `libs/MyKit.framework/` (trailing slash) or produced by string concatenation that left a dangling separator; misconfigured CI variable expanding to nothing inside a longer path.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at crates/tauri-build/src/lib.rs:177

  let src_path = src_dir.join(&src_name);
  if src_path.exists() {
    copy_dir(&src_path, &dest_dir.join(&src_name))?;
    Ok(true)
  } else {
    Ok(false)
  }
}

// Copies the macOS application bundle frameworks to the target folder
fn copy_frameworks(dest_dir: &Path, frameworks: &[String]) -> Result<()> {
  fs::create_dir_all(dest_dir)
    .with_context(|| format!("Failed to create frameworks output directory at {dest_dir:?}"))?;
  for framework in frameworks.iter() {
    if framework.ends_with(".framework") {
      let src_path = Path::new(framework);
      let src_name = src_path
        .file_name()
        .expect("Couldn't get framework filename");
      let dest_path = dest_dir.join(src_name);
      copy_dir(src_path, &dest_path)?;
      continue;
    } else if framework.ends_with(".dylib") {
      let src_path = Path::new(framework);
      if !src_path.exists() {
        return Err(anyhow::anyhow!("Library not found: {}", framework));
      }
      let src_name = src_path.file_name().expect("Couldn't get library filename");
      let dest_path = dest_dir.join(src_name);
      copy_file(src_path, &dest_path)?;
      continue;
    } else if framework.contains('/') {
      return Err(anyhow::anyhow!(
        "Framework path should have .framework extension: {}",
        framework
      ));
    }

View on GitHub (pinned to 460ec35447)