tauri-apps/tauri · error

Failed to setup handlebar template

Error message

Failed to setup handlebar template

What it means

During the WiX MSI build, tauri-bundler registers the main.wxs Handlebars template. When a custom template path is configured, the template string is compiled with register_template_string; if Handlebars fails to parse/compile it, the crate panics via .expect("Failed to setup handlebar template") (the custom-template branch panics with "Failed to setup custom handlebar template"). This aborts bundling immediately because an unparseable template means no installer can be generated.

Solutions

  1. Open the custom .wxs template and fix the Handlebars syntax error (check every {{#if}}/{{#each}} has a matching closing tag).
  2. Test the template against the built-in one: temporarily remove bundle.windows.wix.template from tauri.conf.json to confirm the stock template builds.
  3. Update your custom template to match the current tauri-bundler main.wxs (copy from the tauri-bundler version you use and re-apply your edits).
  4. Verify the template file is valid UTF-8 and not truncated.

Example fix

// before (tauri.conf.json)
"wix": { "template": "installer/main.wxs" }  // template has unclosed {{#if}}

// after
// fix installer/main.wxs:
// {{#if product_version}} ... {{/if}}   <- ensure every block is closed
Defensive patterns

Strategy: validation

Validate before calling

// validate custom wix template before bundling
let tpl = std::fs::read_to_string("installer/main.wxs")?;
handlebars::Handlebars::new().register_template_string("main.wxs", tpl)
  .map_err(|e| anyhow!("invalid wix template: {}", e))?;

Type guard

fn is_valid_template(h: &handlebars::Handlebars, name: &str, src: &str) -> bool {
  h.register_template_string(name, src).is_ok()
}

Try / catch

// in Rust the panic aborts the process; run bundling in a subprocess and surface stderr,
// or pre-validate the template as above before calling bundle_project.

Prevention

When it happens

Trigger: Calling bundle_project with bundle.windows.wix.template set to a custom .wxs file whose content fails Handlebars compilation (malformed Handlebars syntax such as unclosed {{#if}} blocks, bad helper usage, or invalid characters). The map_err to String then expect turns the compile error into a panic.

Common situations: Users copy an old main.wxs from a previous tauri version into their Tauri config; template variables/helpers changed between tauri-bundler releases, so the custom template no longer compiles. Also hand-edited templates with mismatched {{/each}} or {{#if}} tags, or a template saved with the wrong encoding.

Related errors


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

Appendix: source

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

    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()),
      ),
    );

    // Create the update task XML
    let skip_uac_task = Handlebars::new();
    let xml = include_str!("./update-task.xml");
    let update_content = skip_uac_task.render_template(xml, &data)?;

View on GitHub (pinned to 460ec35447)