tauri-apps/tauri · error

failed to convert merge module filename to string

Error message

failed to convert merge module filename to string

What it means

Immediately after extracting the merge module filename, get_merge_modules converts it from OsString to String with into_string().expect("failed to convert merge module filename to string"). This panics when the .msm filename contains non-UTF-8 bytes.

Solutions

  1. Rename the .msm files to ASCII-only names before bundling.
  2. Enable UTF-8 codepage on Windows (system locale settings) or fix the source of the oddly-encoded filenames.
  3. Patch the code to use to_string_lossy() so non-UTF-8 filenames are handled instead of panicking.

Example fix

// before
.into_string().expect("failed to convert merge module filename to string");

// after
.to_string_lossy().into_owned();
Defensive patterns

Strategy: validation

Validate before calling

// ensure every .msm filename is UTF-8 before bundling
for entry in glob("**/*.msm")? {
  let p = entry?;
  if p.file_name().and_then(|n| n.to_str()).is_none() {
    return Err(anyhow!("non-UTF-8 merge module name: {}", p.to_string_lossy()));
  }
}

Type guard

fn is_utf8_os(s: &std::ffi::OsStr) -> bool { s.to_str().is_some() }

Try / catch

// catch via subprocess isolation; instruct users to rename .msm files to ASCII names.

Prevention

When it happens

Trigger: Calling bundle_project when an .msm file inside the merge-modules directory has a filename with non-UTF-8 characters (e.g. encoded in a legacy Windows codepage), so into_string() returns Err.

Common situations: Merge modules downloaded/copied from external sources with localized filenames (accented or CJK characters) stored with a legacy codepage on a Windows machine not using UTF-8.

Related errors


AI-assisted analysis of tauri-apps/tauri@460ec35447 (2026-09-18). Data as JSON: /api/errors/19b6d20630693208. Report an issue: GitHub.

Appendix: source

Thrown at crates/tauri-bundler/src/bundle/windows/msi/mod.rs:988

}

fn get_merge_modules(settings: &Settings) -> crate::Result<Vec<MergeModule>> {
  let mut merge_modules = Vec::new();
  let regex = Regex::new(r"[^\w\d\.]")?;
  for msm in glob::glob(
    &PathBuf::from(glob::Pattern::escape(
      &settings.project_out_directory().to_string_lossy(),
    ))
    .join("*.msm")
    .to_string_lossy(),
  )? {
    let path = msm?;
    let filename = path
      .file_name()
      .expect("failed to extract merge module filename")
      .to_os_string()
      .into_string()
      .expect("failed to convert merge module filename to string");
    merge_modules.push(MergeModule {
      name: regex.replace_all(&filename, "").to_string(),
      path: path.to_string_lossy().to_string(),
    });
  }
  Ok(merge_modules)
}

/// Generates the data required for the resource bundling on wix
fn generate_resource_data(settings: &Settings) -> crate::Result<ResourceDirectory> {
  let cwd = std::env::current_dir()?;

  let mut root_resource_directory = ResourceDirectory::default();
  let mut added_resources = HashSet::new();

  for resource in settings.resource_files().iter() {
    let resource = resource?;

View on GitHub (pinned to 460ec35447)