tauri-apps/tauri · error

failed to read plugin manifest map

Error message

failed to read plugin manifest map

What it means

Thrown at build time when tauri-codegen finds the ACL/plugin manifest map file (ACL_MANIFESTS_FILE_NAME, e.g. acl-manifests.json) in the build output directory but `std::fs::read_to_string` fails to read it. The file exists (checked just before) so the read failure is typically permissions, it having been removed/raced between check and read, or it being a directory/invalid path. The build cannot continue without the manifest map.

Solutions

  1. Delete the stale generated file (or `cargo clean` / remove the tauri build output dir) and rebuild.
  2. Check file permissions/ownership of the generated manifests file in the out dir and fix them (or rebuild as the same user).
  3. Avoid running multiple builds concurrently into the same target directory.
  4. Re-run the tauri CLI so the manifests are regenerated cleanly.

Example fix

# before: stale unreadable generated file
rm -rf src-tauri/target/release/build/*/out
# then rebuild
cargo tauri build
Defensive patterns

Strategy: validation

Validate before calling

const path = 'src-tauri/target/release/build';
// before building, ensure no stale root-owned generated files:
const fs = require('fs');
for (const f of findFiles(path, 'acl-manifests.json')) {
  const st = fs.statSync(f);
  if (!Number(process.getuid?.() ?? 0) !== 0 && st.uid !== process.getuid?.()) {
    console.warn(`unreadable generated file (owner uid ${st.uid}): ${f} — clean it`);
  }
}

Prevention

When it happens

Trigger: Running `tauri build`/`tauri dev` when the previously generated ACL manifests file exists in the target output dir but is unreadable: permission changes, file deleted between `exists()` and read, or the path became a directory.

Common situations: Dirty target directories from previous builds with different permissions; builds run as different users (root vs user) leaving root-owned generated files; concurrent builds racing on the same output dir.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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

Appendix: source

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

          "The isolation application does not contain a file setting the `window.__TAURI_ISOLATION_HOOK__` value."
        );
      }

      let schema = options.isolation_schema;

      quote!(#root::Pattern::Isolation {
        assets: ::std::sync::Arc::new(#assets),
        schema: #schema.into(),
        key: #key.into(),
        crypto_keys: std::boxed::Box::new(::tauri::utils::pattern::isolation::Keys::new().expect("unable to generate cryptographically secure keys for Tauri \"Isolation\" Pattern")),
      })
    }
  };

  let acl_file_path = out_dir.join(ACL_MANIFESTS_FILE_NAME);
  let acl: BTreeMap<String, Manifest> = if acl_file_path.exists() {
    let acl_file =
      std::fs::read_to_string(acl_file_path).expect("failed to read plugin manifest map");
    serde_json::from_str(&acl_file).expect("failed to parse plugin manifest map")
  } else {
    Default::default()
  };

  let capabilities_file_path = out_dir.join(CAPABILITIES_FILE_NAME);
  let capabilities_from_files = if capabilities_file_path.exists() {
    let capabilities_json =
      std::fs::read_to_string(&capabilities_file_path).expect("failed to read capabilities");
    serde_json::from_str(&capabilities_json).expect("failed to parse capabilities")
  } else {
    Default::default()
  };
  let capabilities = get_capabilities(
    &config,
    capabilities_from_files,
    additional_capabilities.as_deref(),
  )

View on GitHub (pinned to 460ec35447)