{"record":{"id":"74caead4a388f57d","repo":"tauri-apps/tauri","slug":"couldn-t-get-framework-filename","errorCode":null,"errorMessage":"Couldn't get framework filename","messagePattern":"Couldn't get framework filename","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/tauri-build/src/lib.rs","lineNumber":177,"sourceCode":"  let src_path = src_dir.join(&src_name);\n  if src_path.exists() {\n    copy_dir(&src_path, &dest_dir.join(&src_name))?;\n    Ok(true)\n  } else {\n    Ok(false)\n  }\n}\n\n// Copies the macOS application bundle frameworks to the target folder\nfn copy_frameworks(dest_dir: &Path, frameworks: &[String]) -> Result<()> {\n  fs::create_dir_all(dest_dir)\n    .with_context(|| format!(\"Failed to create frameworks output directory at {dest_dir:?}\"))?;\n  for framework in frameworks.iter() {\n    if framework.ends_with(\".framework\") {\n      let src_path = Path::new(framework);\n      let src_name = src_path\n        .file_name()\n        .expect(\"Couldn't get framework filename\");\n      let dest_path = dest_dir.join(src_name);\n      copy_dir(src_path, &dest_path)?;\n      continue;\n    } else if framework.ends_with(\".dylib\") {\n      let src_path = Path::new(framework);\n      if !src_path.exists() {\n        return Err(anyhow::anyhow!(\"Library not found: {}\", framework));\n      }\n      let src_name = src_path.file_name().expect(\"Couldn't get library filename\");\n      let dest_path = dest_dir.join(src_name);\n      copy_file(src_path, &dest_path)?;\n      continue;\n    } else if framework.contains('/') {\n      return Err(anyhow::anyhow!(\n        \"Framework path should have .framework extension: {}\",\n        framework\n      ));\n    }","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/tauri-apps/tauri/blob/460ec35447493200d64290dd7f015d5a91d0fd58/crates/tauri-build/src/lib.rs#L159-L195","documentation":"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.","triggerScenarios":"tauri_build::try_build with Attributes::copy_frameworks containing a `.framework` path lacking a filename component, e.g. `\"../\"`-relative or trailing-slash paths.","commonSituations":"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.","solutions":["Remove trailing slashes / `..` components from the framework path so it ends in `Name.framework`.","Verify the framework path in tauri.conf.json points at the bundle directory itself, not its parent.","If the path comes from an env var or script, print it during build to confirm it is non-empty and well-formed.","Pre-resolve the path (canonicalize) and assert `path.file_name().is_some()` before configuring the build."],"exampleFix":"// before\n\"frameworks\": [\"libs/MyKit.framework/\"]\n// after\n\"frameworks\": [\"libs/MyKit.framework\"]","handlingStrategy":"validation","validationCode":"for fw in frameworks {\n  let p = std::path::Path::new(fw);\n  assert!(fw.ends_with(\".framework\") && !fw.ends_with('/'), \"malformed framework path: {fw}\");\n  assert!(p.file_name().is_some(), \"no filename in framework path: {fw}\");\n}","typeGuard":"fn has_file_name(p: &std::path::Path) -> bool { p.file_name().is_some() }","tryCatchPattern":null,"preventionTips":["Write framework paths without trailing slashes; end with `Name.framework`.","Avoid `..` in configured paths; prefer workspace-relative or absolute clean paths.","Validate macOS framework lists on Linux CI using pure path checks before cross-building."],"tags":["build","macos","path","panic","framework"],"backgroundTag":"invalid-argument-format","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"}