tauri-apps/tauri · error

failed to get bundle filename

Error message

failed to get bundle filename

What it means

Panic in tauri-macos-sign's notarization: app_bundle_path.file_stem().expect("failed to get bundle filename") returns None only when the path has no filename component — the filesystem root, an empty path, or a path ending in `..`. notarize()/notarize_and_wait() expect a real `<Name>.app` bundle path; a degenerate path aborts before the zip step.

Source

Thrown at crates/tauri-macos-sign/src/lib.rs:145

}

pub fn notarize_without_stapling(
  keychain: &Keychain,
  app_bundle_path: &Path,
  auth: &AppleNotarizationCredentials,
) -> Result<()> {
  notarize_inner(keychain, app_bundle_path, auth, false)
}

fn notarize_inner(
  keychain: &Keychain,
  app_bundle_path: &Path,
  auth: &AppleNotarizationCredentials,
  wait: bool,
) -> Result<()> {
  let bundle_stem = app_bundle_path
    .file_stem()
    .expect("failed to get bundle filename");

  let tmp_dir = tempfile::tempdir().map_err(Error::TempDir)?;
  let zip_path = tmp_dir
    .path()
    .join(format!("{}.zip", bundle_stem.to_string_lossy()));
  let zip_args = vec![
    "-c",
    "-k",
    "--keepParent",
    "--sequesterRsrc",
    app_bundle_path
      .to_str()
      .expect("failed to convert bundle_path to string"),
    zip_path
      .to_str()
      .expect("failed to convert zip_path to string"),
  ];

View on GitHub (pinned to 52e4b6e71d)

Solutions

  1. Log the bundle path right before notarizing and confirm it ends in a real `<Name>.app` component
  2. Fix the path construction: guard pop()/parent() chains, require the env var that names the .app
  3. Validate in your wrapper: path.file_stem().is_some() and extension == "app" before calling the API

Example fix

// before
let bundle = root.join(std::env::var("APP_PATH").unwrap_or_default()); // may be degenerate
notary.notarize(&keychain, &bundle, &auth, true)?;

// after
let bundle = root.join(std::env::var("APP_PATH").expect("APP_PATH unset"));
assert!(bundle.extension().is_some_and(|e| e == "app"));
notary.notarize(&keychain, &bundle, &auth, true)?;
Defensive patterns

Strategy: validation

Validate before calling

use std::path::Path;
fn is_app_bundle(p: &Path) -> bool {
    p.file_stem().is_some() && p.extension().is_some_and(|e| e == "app")
}
assert!(is_app_bundle(&bundle); // before notarize()

Prevention

When it happens

Trigger: Calling notarize (directly or via the tauri-cli macOS signing flow) with a path like "/", "", or one ending in `..` — typically the result of path-manipulation bugs such as one pop()/parent() too many, or joining an unset environment variable.

Common situations: CI scripts assembling the .app path from env vars where one is empty; glob results passed to the signer without validation; refactor of path handling in release scripts.

Related errors


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