tauri-apps/tauri · error

Failed to setup custom handlebar template

Error message

Failed to setup custom handlebar template

What it means

Panic from `.expect("Failed to setup custom handlebar template")` in `build_wix_app_installer`. After reading the user's custom `main.wxs` template file, the bundler registers it with Handlebars; if the template contains invalid Handlebars syntax (unbalanced `{{#if}}`/`{{/if}}`, bad helpers, malformed expressions), `register_template_string` fails and the bundler panics. It is distinct from the built-in template path: the built-in `main.wxs` cannot fail, only a user-supplied one can.

Solutions

  1. Validate the custom template's Handlebars syntax: check every `{{#each}}`/`{{#if}}` has a matching `{{/each}}`/`{{/if}}` and escape literal `{{` as `{{{"{{"}}}` style raw blocks where needed
  2. Start from the built-in template shipped with your tauri-bundler version (`main.wxs` in the crate) and modify incrementally, testing after each change
  3. Remove or correct unsupported helper calls; only helpers registered by tauri-bundler are available in the template
  4. Temporarily unset `windows.wix.template` to confirm the built-in template bundles, then bisect your custom template

Example fix

// tauri.conf.json -> custom main.wxs
// before
{{#if productLanguage}}
  <Product Language="en-US"/>
{{/if productLanguage}}
// after (balanced close)
{{#if productLanguage}}
  <Product Language="en-US"/>
{{/if}}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-validate custom template balance before configuring it
let tpl = std::fs::read_to_string(custom_wxs_path)?;
let opens = tpl.matches("{{#").count();
let closes = tpl.matches("{{/").count();
if opens != closes {
    return Err(format!(
        "unbalanced handlebars blocks: {} open vs {} close",
        opens, closes
    ));
}

Try / catch

// mirror the bundler's logic locally to get a real error instead of a panic
match handlebars.register_template_string("main.wxs", tpl) {
    Ok(_) => {},
    Err(e) => return Err(anyhow!("invalid custom WiX template: {e}")),
}

Prevention

When it happens

Trigger: Providing a custom WiX template via `windows.wix.template` in tauri.conf.json (or the equivalent bundle config) whose content is not valid Handlebars syntax; the file reads fine (`fs::read_to_string` succeeded) but template compilation fails.

Common situations: Hand-edited WiX templates with mismatched block tags, copying a template from an incompatible Tauri/WiX version whose expected variables changed, missing closing braces or stray `{{` characters, or referencing unregistered helpers in the custom template.

Related errors


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

Appendix: source

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

  if let Some(file_associations) = settings.file_associations() {
    data.insert("file_associations", to_json(file_associations));
  }

  if let Some(protocols) = settings.deep_link_protocols() {
    let schemes = protocols
      .iter()
      .flat_map(|p| &p.schemes)
      .collect::<Vec<_>>();
    if !schemes.is_empty() {
      data.insert("deep_link_protocols", to_json(schemes));
    }
  }

  if let Some(path) = custom_template_path {
    handlebars
      .register_template_string("main.wxs", fs::read_to_string(path)?)
      .map_err(|e| e.to_string())
      .expect("Failed to setup custom handlebar template");
  } else {
    handlebars
      .register_template_string("main.wxs", include_str!("./main.wxs"))
      .map_err(|e| e.to_string())
      .expect("Failed to setup handlebar template");
  }

  if enable_elevated_update_task {
    data.insert(
      "msiexec_args",
      to_json(
        settings
          .updater()
          .map(|updater| updater.msiexec_args)
          .map(|args| args.join(" "))
          .unwrap_or_else(|| "/passive".to_string()),
      ),
    );

View on GitHub (pinned to 460ec35447)