tauri-apps/tauri · error

Couldn't get framework filename

Error message

Couldn't get framework filename

What it means

In the macOS bundler's copy_frameworks_to_bundle, `.framework` entries are copied by joining the source's `file_name()` to the bundle's Frameworks directory. When the framework path lacks a final component, file_name() returns None and the expect panics. The bundler assumes every configured framework path ends in `Name.framework`.

Solutions

  1. Remove trailing separators and `..` so each entry ends in `Name.framework`.
  2. Confirm each framework path exists at build time and points at the .framework bundle directory.
  3. Use absolute or workspace-relative clean paths in the frameworks list.
  4. If paths come from a script, validate `path.file_name().is_some()` before invoking the bundler.

Example fix

// before
"frameworks": ["../Frameworks/Spark.framework/"]
// after
"frameworks": ["../Frameworks/Spark.framework"]
Defensive patterns

Strategy: validation

Validate before calling

for fw in frameworks {
  let p = std::path::PathBuf::from(fw);
  assert!(fw.ends_with(".framework") && p.file_name().is_some(), "bad framework path: {fw}");
  assert!(p.exists(), "framework not found: {fw}");
}

Type guard

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

Prevention

When it happens

Trigger: tauri build producing a macOS .app with `bundle.macOS.frameworks` (or equivalent settings) containing a `.framework` path with a trailing slash, `..`, or otherwise no filename component.

Common situations: Config entries like `"Frameworks/MyKit.framework/"`; CI variables expanding to leave a dangling separator; switching from a file to a directory path without updating the config.

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/7042251aa525e5e2. Report an issue: GitHub.

Appendix: source

Thrown at crates/tauri-bundler/src/bundle/macos/app.rs:401

// Copies the macOS application bundle frameworks to the .app
fn copy_frameworks_to_bundle(
  bundle_directory: &Path,
  settings: &Settings,
) -> crate::Result<Vec<SignTarget>> {
  let mut paths = Vec::new();

  let frameworks = settings.macos().frameworks.clone().unwrap_or_default();
  if frameworks.is_empty() {
    return Ok(paths);
  }
  let dest_dir = bundle_directory.join("Frameworks");
  fs::create_dir_all(&dest_dir).fs_context("failed to create Frameworks directory", &dest_dir)?;
  for framework in frameworks.iter() {
    if framework.ends_with(".framework") {
      let src_path = PathBuf::from(framework);
      let src_name = src_path
        .file_name()
        .expect("Couldn't get framework filename");
      let dest_path = dest_dir.join(src_name);
      fs_utils::copy_dir(&src_path, &dest_path)?;
      add_framework_sign_path(&src_path, &dest_path, &mut paths);
      continue;
    } else if framework.ends_with(".dylib") {
      let src_path = PathBuf::from(framework);
      if !src_path.exists() {
        return Err(GenericError(format!("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);
      fs_utils::copy_file(&src_path, &dest_path)?;
      paths.push(SignTarget {
        path: dest_path,
        is_an_executable: false,
      });
      continue;
    } else if framework.contains('/') {

View on GitHub (pinned to 460ec35447)