tauri-apps/tauri · error · anyhow::Error
Library not found: {}
Error message
Library not found: {} What it means
On macOS, tauri-build processes each entry of bundle.macOS.frameworks: entries ending in .framework are copied as directories, and entries ending in .dylib are treated as literal file paths. This error fires when a .dylib entry's path does not exist on disk before copy_file runs.
Source
Thrown at crates/tauri-build/src/lib.rs:184
}
// 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
));
}
if let Some(home_dir) = dirs::home_dir() {
if copy_framework_from(&home_dir.join("Library/Frameworks/"), framework, dest_dir)? {
continue;
}
}
if copy_framework_from("/Library/Frameworks/".as_ref(), framework, dest_dir)?
|| copy_framework_from("/Network/Library/Frameworks/".as_ref(), framework, dest_dir)?View on GitHub (pinned to 2f1cd75b0f)
Solutions
- Fix the path in tauri.conf.json so it resolves to the existing .dylib file
- Generate/compile the dylib before tauri build (hook it into beforeBuildCommand if it is a build artifact)
- If you meant a system-installed framework, use a bare name (no slash) or a .framework path instead of a .dylib path
Example fix
// before
"macOS": { "frameworks": ["lib/native/libmylib.dylib"] } // file missing
// after
"macOS": { "frameworks": ["libs/libmylib.dylib"] } // path exists Defensive patterns
Strategy: validation
Validate before calling
# prebuild check: every .dylib frameworks entry must exist for p in $(jq -r '.bundle.macOS.frameworks[]?' src-tauri/tauri.conf.json 2>/dev/null | grep '\.dylib$'); do [ -f "src-tauri/$p" ] || echo "missing dylib: $p" done
Prevention
- Generate dylibs in beforeBuildCommand so they exist before tauri build
- Use repo-relative paths, not machine-specific absolute paths
- CI on a clean checkout will catch paths that only exist on dev machines - run it before release
When it happens
Trigger: Building on macOS with bundle.macOS.frameworks containing a '.dylib'-suffixed path (relative or absolute) that is not present at build time - typo'd path, dylib produced by another crate or prebuild step that never ran, or path relative to the wrong working directory.
Common situations: Linking a dylib built by a workspace crate whose build step hasn't run; absolute paths valid on one machine but not CI; moving dylibs without updating tauri.conf.json.
Related errors
- Framework path should have .framework extension: {}
- Permission {} not found, expected one of {}
- {:?} does not exist
- {:?} is not a file
- `{}` not found; required for generating a Windows Resource f
AI-assisted analysis of tauri-apps/tauri@2f1cd75b0f (2026-08-16).
Data as JSON: /api/errors/f3a4be779ce5cf14.
Report an issue: GitHub.