{"record":{"id":"c090d8d9f4788e3a","repo":"tauri-apps/tauri","slug":"failed-to-extract-external-binary-filename-lib","errorCode":null,"errorMessage":"failed to extract external binary filename","messagePattern":"failed to extract external binary filename","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/tauri-build/src/lib.rs","lineNumber":69,"sourceCode":"  }\n  let dest_dir = to.parent().expect(\"No data in parent\");\n  fs::create_dir_all(dest_dir)?;\n  fs::copy(from, to)?;\n  Ok(())\n}\n\nfn copy_binaries(\n  binaries: ResourcePaths,\n  target_triple: &str,\n  path: &Path,\n  package_name: Option<&str>,\n) -> Result<()> {\n  for src in binaries {\n    let src = src?;\n    println!(\"cargo:rerun-if-changed={}\", src.display());\n    let file_name = src\n      .file_name()\n      .expect(\"failed to extract external binary filename\")\n      .to_string_lossy()\n      .replace(&format!(\"-{target_triple}\"), \"\");\n\n    if package_name == Some(&file_name) {\n      return Err(anyhow::anyhow!(\n        \"Cannot define a sidecar with the same name as the Cargo package name `{}`. Please change the sidecar name in the filesystem and the Tauri configuration.\",\n        file_name\n      ));\n    }\n\n    let dest = path.join(file_name);\n    if dest.exists() {\n      fs::remove_file(&dest).unwrap();\n    }\n    copy_file(&src, &dest)?;\n  }\n  Ok(())\n}","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/tauri-apps/tauri/blob/460ec35447493200d64290dd7f015d5a91d0fd58/crates/tauri-build/src/lib.rs#L51-L87","documentation":"In tauri-build's copy_binaries, each external binary path is expected to have a final file name component; `Path::file_name()` returned None, so the `.expect` panics with this message. The library assumes sidecar paths always point to an actual file, and needs the filename to strip the target-triple suffix. It is a build-time panic, not a recoverable Result.","triggerScenarios":"Passing an `externalBin` entry whose path has no file name component — e.g. a path ending in `/`, `..`, `.`, or the filesystem root — to tauri_build::try_build via Attributes::copy_binaries.","commonSituations":"A Tauri config `bundle.externalBin` entry like `binaries/myapp-` or a mis-resolved path from a build script; generated paths where a variable was empty so the path collapses to a directory-like value; paths built by joining with trailing separators.","solutions":["Fix the external binary path in tauri.conf.json so it ends with an actual file name (e.g. `binaries/myapp`).","Verify the referenced sidecar binary exists and the path is not truncated (empty variable, missing extension handling).","If building paths in a build script, normalize with `path.canonicalize()` or `std::path::absolute` before passing to copy_binaries.","Assert the path with `assert!(src.is_file())` in your build script before calling try_build to fail early with a clearer message."],"exampleFix":"// before (tauri.conf.json)\n\"externalBin\": [\"binaries/\"]\n// after\n\"externalBin\": [\"binaries/my-sidecar\"]","handlingStrategy":"validation","validationCode":"let src = std::path::Path::new(\"binaries/my-sidecar\");\nassert!(src.is_file(), \"sidecar path is not a file: {}\", src.display());\nassert!(src.file_name().is_some(), \"sidecar path has no filename component\");","typeGuard":"fn has_file_name(p: &std::path::Path) -> bool { p.file_name().is_some() }","tryCatchPattern":null,"preventionTips":["Always end externalBin entries with the binary file name; the target triple suffix is appended automatically.","Never build sidecar paths from possibly-empty variables without a fallback.","Run `tauri build` locally for the same target before CI to catch config path issues early."],"tags":["build","path","panic","sidecar"],"backgroundTag":"null-argument","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"}