tauri-apps/tauri · error
failed to extract external binary filename
Error message
failed to extract external binary filename
What it means
copy_binaries copies each configured external binary (sidecar, from bundle.externalBin) into the bundle, deriving the destination name from the source's file_name. file_name() is None when the path is a root or ends with '..', so a degenerate externalBin path panics here during bundling.
Source
Thrown at crates/tauri-bundler/src/bundle/settings.rs:1208
pub fn external_binaries(&self) -> ResourcePaths<'_> {
match self.bundle_settings.external_bin {
Some(ref paths) => ResourcePaths::new(paths.as_slice(), true),
None => ResourcePaths::new(&[], true),
}
}
/// Copies external binaries to a path.
///
/// Returns the list of destination paths.
pub fn copy_binaries(&self, path: &Path) -> crate::Result<Vec<PathBuf>> {
let mut paths = Vec::new();
for src in self.external_binaries() {
let src = src?;
let dest = path.join(
src
.file_name()
.expect("failed to extract external binary filename")
.to_string_lossy()
.replace(&format!("-{}", self.target), ""),
);
fs_utils::copy_file(&src, &dest)?;
paths.push(dest);
}
Ok(paths)
}
/// Copies resources to a path.
pub fn copy_resources(&self, path: &Path) -> crate::Result<()> {
for resource in self.resource_files().iter() {
let resource = resource?;
let dest = path.join(resource.target());
fs_utils::copy_file(resource.path(), &dest)?;
}
Ok(())
}View on GitHub (pinned to 52e4b6e71d)
Solutions
- Fix the externalBin entry to point at the sidecar file including its target-triple suffix, e.g. binaries/my-sidecar-x86_64-unknown-linux-gnu
- Check generated tauri.conf.json for unset variables or copy-paste typos that strip the file name
- Confirm each sidecar file actually exists with the -<target> suffix before bundling
Example fix
// tauri.conf.json — before "externalBin": ["binaries/"] // after "externalBin": ["binaries/my-sidecar-x86_64-unknown-linux-gnu"]
Defensive patterns
Strategy: validation
Validate before calling
// validate externalBin entries before building
const last = (p) => p.split('/').pop() ?? '';
const bad = (config.bundle.externalBin ?? []).filter((p) => ['', '.', '..'].includes(last(p)));
if (bad.length) throw new Error(`externalBin entries without a file name: ${bad.join(', ')}`); Type guard
const hasSidecarFileName = (p) => { const seg = p.split('/').pop() ?? ''; return seg.length > 0 && seg !== '.' && seg !== '..'; }; Prevention
- Every externalBin entry must name a file with the -<target-triple> suffix, never a bare directory
- Validate generated tauri.conf.json with its JSON schema in CI before invoking the bundler
- Fail template interpolation on unset variables instead of emitting empty path tails
When it happens
Trigger: tauri build with a bundle.externalBin entry in tauri.conf.json such as '..', a root, or a directory-like path with no final file component, so src.file_name() returns None while copying sidecars.
Common situations: Script-generated configs with empty variable interpolation (e.g. "binaries/${NAME}" with NAME unset collapsing to a bare directory); typos; copying example configs with incomplete paths.
Related errors
- failed to extract external binary filename
- {:?} does not exist
- {:?} is not a file
- cannot use both `resources` and `resources_map`
- Cannot define a sidecar with the same name as the Cargo pack
AI-assisted analysis of tauri-apps/tauri@52e4b6e71d (2026-08-20).
Data as JSON: /api/errors/653e85b26f55d786.
Report an issue: GitHub.