tauri-apps/tauri · critical

cannot use both `resources` and `resources_map`

Error message

cannot use both `resources` and `resources_map`

What it means

The bundler's resource gathering accepts resources either as a plain list (resources) or as a map from source to target (resources_map), but not both. BundleSettings::resources() panics when both fields are set in the Tauri configuration.

Solutions

  1. Remove either bundle.resources or bundle.resources_map from tauri.conf.json so only one remains
  2. If merging configs, exclude the conflicting key in the platform-specific fragment
  3. Convert the list entries into map entries if you need per-file target paths

Example fix

// before (tauri.conf.json)
"resources": ["assets/*"], "resources_map": {"a.txt": "b.txt"}
// after
"resources_map": {"assets/*": "assets/", "a.txt": "b.txt"}
Defensive patterns

Strategy: validation

Validate before calling

const conf = JSON.parse(readFileSync('tauri.conf.json', 'utf8'));
if (conf.bundle?.resources && conf.bundle?.resources_map)
  throw new Error('Set either bundle.resources or bundle.resources_map, not both');

Type guard

function hasConflictingResources(b?: { resources?: unknown; resources_map?: unknown }): boolean {
  return b != null && b.resources != null && b.resources_map != null;
}

Prevention

When it happens

Trigger: tauri.conf.json's bundle section defines both bundle.resources and bundle.resources_map at the same time, so the (Some, Some) match arm triggers the panic.

Common situations: Merging config fragments (e.g. platform-specific conf JSON or a merge tool) where each side adds one of the two keys; migrating to resources_map without removing the old resources array.

Related errors


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

Appendix: source

Thrown at crates/tauri-bundler/src/bundle/settings.rs:1183

  /// Returns an iterator over the icon files to be used for this bundle.
  pub fn icon_files(&self) -> ResourcePaths<'_> {
    match self.icon_files {
      Some(ref paths) => ResourcePaths::new(paths.as_slice(), false),
      None => ResourcePaths::new(&[], false),
    }
  }

  /// Returns an iterator over the resource files to be included in this
  /// bundle.
  pub fn resource_files(&self) -> ResourcePaths<'_> {
    match (
      &self.bundle_settings.resources,
      &self.bundle_settings.resources_map,
    ) {
      (Some(paths), None) => ResourcePaths::new(paths.as_slice(), true),
      (None, Some(map)) => ResourcePaths::from_map(map, true),
      (Some(_), Some(_)) => panic!("cannot use both `resources` and `resources_map`"),
      (None, None) => ResourcePaths::new(&[], true),
    }
  }

  /// Returns an iterator over the external binaries to be included in this
  /// bundle.
  pub fn external_binaries(&self) -> ResourcePaths<'_> {
    match self.bundle_settings.external_bin {
      Some(ref paths) => ResourcePaths::new(paths.as_slice(), true),
      None => ResourcePaths::new(&[], true),
    }
  }

  /// Copies external binaries to a path.
  ///
  /// Returns the list of destination paths.
  pub fn copy_binaries(&self, path: &Path) -> crate::Result<Vec<PathBuf>> {
    let mut paths = Vec::new();

View on GitHub (pinned to 460ec35447)