tauri-apps/tauri · error

failed to convert bundle filename to string

Error message

failed to convert bundle filename to string

What it means

Panic in tauri-macos-sign's staple step: the bundle filename from file_name() is converted with .to_str().expect("failed to convert bundle filename to string"), which fails when the filename contains bytes that are not valid UTF-8. `xcrun stapler staple` needs a string argument, so a non-UTF-8 .app name aborts stapling.

Source

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

        String::from_utf8_lossy(&output.stdout)
      )))
    } else {
      Err(Error::Notarize(log_message))
    }
  } else {
    Err(Error::ParseNotarytoolOutput {
      output: output_str.into_owned(),
    })
  }
}

fn staple_app(mut app_bundle_path: PathBuf) -> Result<()> {
  let app_bundle_path_clone = app_bundle_path.clone();
  let filename = app_bundle_path_clone
    .file_name()
    .expect("failed to get bundle filename")
    .to_str()
    .expect("failed to convert bundle filename to string");

  app_bundle_path.pop();

  Command::new("xcrun")
    .args(vec!["stapler", "staple", "-v", filename])
    .current_dir(app_bundle_path)
    .output()
    .map_err(|error| Error::CommandFailed {
      command: "xcrun stapler staple".to_string(),
      error,
    })?;

  Ok(())
}

pub trait NotarytoolCmdExt {
  fn notarytool_args(
    &mut self,

View on GitHub (pinned to 52e4b6e71d)

Solutions

  1. Rename the .app to pure ASCII/UTF-8 before stapling
  2. Regenerate the artifact from a clean pipeline step
  3. Validate in your wrapper: path.file_name().and_then(|n| n.to_str()).is_some() before invoking the flow

Example fix

# before
staple "My App\xa0.app"  → panic: failed to convert bundle filename to string

# after
mv "$(printf 'My App\xa0.app')" "MyApp.app" && staple "MyApp.app"
Defensive patterns

Strategy: validation

Validate before calling

let name_ok = app_bundle_path
    .file_name()
    .and_then(|n| n.to_str())
    .is_some_and(|n| n.ends_with(".app"));
assert!(name_ok, "bundle filename must be UTF-8 and end in .app");

Type guard

fn utf8_file_name(p: &std::path::Path) -> Option<&str> { p.file_name().and_then(|n| n.to_str()) }

Prevention

When it happens

Trigger: Stapling a bundle whose filename (not the whole path) includes non-UTF-8 bytes — artifact names mangled by archive tools or created on systems with legacy locale encodings.

Common situations: Extracted archives preserving invalid byte sequences; filenames pasted from rich text introducing invisible invalid bytes.

Related errors


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