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

  1. 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
  2. Check generated tauri.conf.json for unset variables or copy-paste typos that strip the file name
  3. 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

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


AI-assisted analysis of tauri-apps/tauri@52e4b6e71d (2026-08-20). Data as JSON: /api/errors/653e85b26f55d786. Report an issue: GitHub.