tauri-apps/tauri · error

failed to serialize plist

Error message

failed to serialize plist

What it means

In tauri-codegen's map_isolation (the isolation pattern codegen), the generated Info.plist is serialized to XML via plist::to_writer_xml and the result is .expect()'d. If the in-memory plist structure cannot be serialized to XML (structurally invalid plist value, e.g. invalid key types), the panic 'failed to serialize plist' fires at compile time of the Tauri app.

Solutions

  1. Review dangerousRemoteDomainIpcAccess / isolation settings in tauri.conf.json; simplify or correct the remote domain/origin entries.
  2. Update tauri (tauri-codegen) to the latest patch version; this may be a fixed codegen bug.
  3. Temporarily disable the isolation pattern to confirm it is the trigger, then re-enable with corrected config.
  4. Check for non-ASCII or special characters in app identifiers/origins that may break plist XML generation.

Example fix

// before (tauri.conf.json)
"dangerousRemoteDomainIpcAccess": [{"scheme": "https", "domain": "my app.example.com", "windows": ["main"], "plugins": ["fs"]}]
// after
"dangerousRemoteDomainIpcAccess": [{"scheme": "https", "domain": "myapp.example.com", "windows": ["main"], "plugins": ["fs"]}]
Defensive patterns

Strategy: validation

Validate before calling

// Validate isolation config before building
let accesses = &config.tauri.dangerous_remote_domain_ipc_access;
for a in accesses {
  assert!(!a.domain.contains(' '), "invalid domain in dangerousRemoteDomainIpcAccess: {}", a.domain);
  assert!(matches!(a.scheme.as_str(), "https" | "http"), "invalid scheme: {}", a.scheme);
}

Prevention

When it happens

Trigger: map_isolation -> map_isolation (called recursively) while codebuilding an app that enables the isolation pattern (dangerousRemoteDomainIpcAccess / isolation origin) and the constructed info_plist value fails XML serialization.

Common situations: Enabling Tauri's isolation pattern with a dangerousRemoteDomainIpcAccess config that produces a plist entry the plist crate cannot represent; a tauri-codegen/plist crate version incompatibility; very unusual origin strings containing characters that break plist serialization.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


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

Appendix: source

Thrown at crates/tauri-codegen/src/context.rs:338

      }

      if let Some(version) = &config.version {
        let bundle_version = &config.bundle.macos.bundle_version;
        plist.insert("CFBundleShortVersionString".into(), version.clone().into());
        plist.insert(
          "CFBundleVersion".into(),
          bundle_version
            .clone()
            .unwrap_or_else(|| version.clone())
            .into(),
        );
      }
    }

    let mut plist_contents = std::io::BufWriter::new(Vec::new());
    info_plist
      .to_writer_xml(&mut plist_contents)
      .expect("failed to serialize plist");
    let plist_contents =
      String::from_utf8_lossy(&plist_contents.into_inner().unwrap()).into_owned();

    let plist = crate::Cached::try_from(plist_contents)?;
    quote!({
      tauri::embed_plist::embed_info_plist!(#plist);
    })
  } else {
    quote!()
  };
  #[cfg(not(target_os = "macos"))]
  let maybe_embed_plist_block = quote!();

  let pattern = match &options.pattern {
    PatternKind::Brownfield => quote!(#root::Pattern::Brownfield),
    #[cfg(not(feature = "isolation"))]
    PatternKind::Isolation { dir: _ } => {
      quote!(#root::Pattern::Brownfield)

View on GitHub (pinned to 460ec35447)