tauri-apps/tauri · error

Failed to create locale file

Error message

Failed to create locale file

What it means

While building the MSI, tauri-bundler writes a locale.wxl file (WiX localization strings, possibly augmented with unset-locale strings) into the WiX output directory. If File::create on locale.wxl fails, the code panics with .expect("Failed to create locale file"). File::create fails when the target directory does not exist or the process lacks write permission.

Solutions

  1. Ensure the bundle output directory (target/release/bundle/msi/...) exists and is writable; re-run the build to regenerate it.
  2. Check disk space and remove any lock on the directory (antivirus scans, open Explorer windows, previous MSI processes).
  3. Run the build with sufficient permissions, or point the output to a user-writable location.
  4. Retry the build — transient AV/file-lock failures usually disappear on a second run.

Example fix

// before
let mut fileout = File::create(&locale_path).expect("Failed to create locale file");

// after
let mut fileout = File::create(&locale_path)
  .with_context(|| format!("failed to create locale file at {}", locale_path.display()))?;
Defensive patterns

Strategy: try-catch

Validate before calling

// precheck before bundling
let dir = std::path::Path::new("target/release/bundle/msi");
fs::create_dir_all(dir)?;
let probe = dir.join(".write_probe");
fs::write(&probe, b"x").map_err(|e| anyhow!("bundle dir not writable: {}", e))?;
let _ = fs::remove_file(&probe);

Try / catch

// run the bundler in a child process and treat a panic here as an environment error:
let status = Command::new("cargo").args(["tauri", "build"]).status()?;
if !status.success() { /* inspect output for 'Failed to create locale file' */ }

Prevention

When it happens

Trigger: Calling bundle_project with bundle.windows.wix.language configured, when the parent directory of output_path/locale.wxl was removed between steps, output_path is read-only, an antivirus/file lock blocks creation, or the path is on a full disk.

Common situations: CI runners with read-only build directories, target/release/bundle cleaned while bundling, antivirus quarantining files mid-build on Windows, or output paths pointing to a drive without space.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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

Appendix: source

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

    for locale_string in locale_strings.split('\n').filter(|s| !s.is_empty()) {
      // strip `<String ` prefix and `>{value}</String` suffix.
      let id = locale_string
        .chars()
        .skip(prefix_len)
        .take(locale_string.find('>').unwrap() - prefix_len)
        .collect::<String>();
      if !locale_contents.contains(&id) {
        unset_locale_strings.push_str(locale_string);
      }
    }

    let locale_contents = locale_contents.replace(
      "</WixLocalization>",
      &format!("{unset_locale_strings}</WixLocalization>"),
    );
    let locale_path = output_path.join("locale.wxl");
    {
      let mut fileout = File::create(&locale_path).expect("Failed to create locale file");
      fileout.write_all(locale_contents.as_bytes())?;
    }

    let arguments = vec![
      format!(
        "-cultures:{}",
        if language == "en-US" {
          language.to_lowercase()
        } else {
          format!("{};en-US", language.to_lowercase())
        }
      ),
      "-loc".into(),
      display_path(&locale_path),
      "*.wixobj".into(),
    ];
    let msi_output_path = output_path.join("output.msi");
    let msi_path =

View on GitHub (pinned to 460ec35447)