tauri-apps/tauri · error
invalid capability
Error message
invalid capability
What it means
RuntimeCapability is implemented for any &str/String: build() parses the string into a CapabilityFile, trying JSON first, then TOML. The expect panics when the string is neither valid JSON nor valid TOML, or does not match the capability schema (missing identifier, malformed permissions/webviews/remote fields). It backs Manager::add_capability, so app.add_capability("...") with a bad string panics.
Source
Thrown at crates/tauri/src/ipc/capability_builder.rs:22
use serde::Serialize;
use tauri_utils::{
acl::{
capability::{Capability, CapabilityFile, PermissionEntry},
Scopes,
},
platform::Target,
};
/// A capability that can be added at runtime.
pub trait RuntimeCapability {
/// Creates the capability file.
fn build(self) -> CapabilityFile;
}
impl<T: AsRef<str>> RuntimeCapability for T {
fn build(self) -> CapabilityFile {
self.as_ref().parse().expect("invalid capability")
}
}
/// A builder for a [`Capability`].
pub struct CapabilityBuilder(Capability);
impl CapabilityBuilder {
/// Creates a new capability builder with a unique identifier.
pub fn new(identifier: impl Into<String>) -> Self {
Self(Capability {
identifier: identifier.into(),
description: "".into(),
remote: None,
local: true,
windows: Vec::new(),
webviews: Vec::new(),
permissions: Vec::new(),
platforms: None,View on GitHub (pinned to 52e4b6e71d)
Solutions
- Pre-parse to see the real error: let r: Result<CapabilityFile, _> = s.parse(); inspect the Err before calling add_capability.
- Use JSON or TOML only, with required fields (identifier, permissions) present.
- If sourcing from a file, read it to a string first (include_str!) and validate contents, not the path.
Example fix
// before
app.add_capability("capabilities/beta/cap.json"); // path, not contents
// after
let raw = include_str!("../capabilities/beta/cap.json");
let parsed: tauri_utils::acl::capability::CapabilityFile = raw.parse().expect("capability file must be valid JSON/TOML");
app.add_capability(raw); Defensive patterns
Strategy: validation
Validate before calling
// validate before handing the string to add_capability
let cap: Result<tauri_utils::acl::capability::CapabilityFile, _> = raw.parse();
assert!(cap.is_ok(), "capability string is not valid JSON/TOML: {:?}", cap.err());
app.add_capability(raw); Type guard
fn is_valid_capability_str(s: &str) -> bool {
s.parse::<tauri_utils::acl::capability::CapabilityFile>().is_ok()
} Prevention
- Use include_str! on capability files, never a bare path string.
- Validate capability strings in unit tests with .parse() before shipping.
- Remember only JSON and TOML are accepted; convert YAML beforehand.
When it happens
Trigger: Passing a malformed or wrong-format capability string to app.add_capability: YAML capability content (only JSON/TOML are parsed), JSON missing required fields such as identifier, or a file path instead of the file contents.
Common situations: Copying a capabilities/*.yaml file's content into runtime code; hand-written JSON typos; passing a path where contents were expected.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- failed to serialize scope
- invalid permission {p}
- failed to parse plugin manifest map
- failed to parse capabilities
- failed to create plugin documentation directory
AI-assisted analysis of tauri-apps/tauri@52e4b6e71d (2026-08-20).
Data as JSON: /api/errors/a198881812723eae.
Report an issue: GitHub.