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
- 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.
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
- 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.
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
- Couldn't get framework filename
- Couldn't get library filename
- Couldn't get library filename
- failed to extract external binary filename
- No data in parent
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)