{"record":{"id":"3793b3ad4badac25","repo":"tauri-apps/tauri","slug":"framework-path-should-have-framework-extension","errorCode":null,"errorMessage":"Framework path should have .framework extension: {}","messagePattern":"Framework path should have \\.framework extension: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tauri-build/src/lib.rs","lineNumber":191,"sourceCode":"    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    }\n    if let Some(home_dir) = dirs::home_dir() {\n      if copy_framework_from(&home_dir.join(\"Library/Frameworks/\"), framework, dest_dir)? {\n        continue;\n      }\n    }\n    if copy_framework_from(\"/Library/Frameworks/\".as_ref(), framework, dest_dir)?\n      || copy_framework_from(\"/Network/Library/Frameworks/\".as_ref(), framework, dest_dir)?\n    {\n      continue;\n    }\n  }\n  Ok(())\n}\n","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/tauri-apps/tauri/blob/460ec35447493200d64290dd7f015d5a91d0fd58/crates/tauri-build/src/lib.rs#L173-L209","documentation":"macOS framework entries in `bundle.macOS.frameworks` must either be a `.framework` bundle path, a `.dylib`, or a bare framework name resolvable in standard Library/Frameworks directories. A value containing '/' that is not one of the handled forms is rejected with this error.","triggerScenarios":"An entry in `bundle.macOS.frameworks` contains a slash (looks like a path) but does not end with `.framework` or `.dylib`, so copy_frameworks cannot classify it.","commonSituations":"Typo like `libs/Foo.framewrk`, pointing at the binary inside a framework bundle (`Foo.framework/Foo`), or an outdated config from a different bundler convention.","solutions":["Change the entry to end with `.framework` (the bundle directory) or `.dylib`","Use just the framework name (e.g. \"Sparkle\") so tauri resolves it from ~/Library/Frameworks or /Library/Frameworks","Remove the stray path if the framework should come from system search paths"],"exampleFix":"// before\n\"frameworks\": [\"libs/Sparkle\"]\n// after\n\"frameworks\": [\"libs/Sparkle.framework\"]","handlingStrategy":"validation","validationCode":"for (const fw of cfg.bundle?.macOS?.frameworks ?? []) {\n  if (fw.includes('/') && !fw.endsWith('.framework') && !fw.endsWith('.dylib')) {\n    throw new Error(`Framework entry must be *.framework or *.dylib: ${fw}`);\n  }\n}","typeGuard":"const isValidFrameworkEntry = (fw: string) => !fw.includes('/') || fw.endsWith('.framework') || fw.endsWith('.dylib');","tryCatchPattern":"try {\n  await buildMac();\n} catch (e) {\n  if (String(e).includes('.framework extension')) throw new Error(`Fix frameworks entry format: ${e.message}`);\n  throw e;\n}","preventionTips":["Reference framework bundles by their .framework directory, never by inner binaries","Use bare names for system/homebrew frameworks","Add a JSON-schema/config lint step for tauri.conf.json"],"tags":["macos","frameworks","config","tauri-build"],"backgroundTag":"invalid-config-value","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"}