{"record":{"id":"532eb272213b08b8","repo":"tauri-apps/tauri","slug":"invalid-permission-p","errorCode":null,"errorMessage":"invalid permission {p}","messagePattern":"invalid permission (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tauri-cli/src/acl/capability/new.rs","lineNumber":97,"sourceCode":"      }\n    })\n    .unwrap_or_default(),\n  };\n\n  let capability = Capability {\n    identifier,\n    description: description.unwrap_or_default(),\n    remote: None,\n    local: true,\n    windows,\n    webviews: Vec::new(),\n    permissions: permissions\n      .into_iter()\n      .map(|p| {\n        PermissionEntry::PermissionRef(\n          p.clone()\n            .try_into()\n            .unwrap_or_else(|_| panic!(\"invalid permission {p}\")),\n        )\n      })\n      .collect(),\n    platforms: None,\n  };\n\n  let path = match options.out {\n    Some(o) => o\n      .canonicalize()\n      .fs_context(\"failed to canonicalize capability file path\", o.clone())?,\n    None => {\n      let capabilities_dir = dirs.tauri.join(\"capabilities\");\n      capabilities_dir.join(format!(\n        \"{}.{}\",\n        capability.identifier,\n        options.format.extension()\n      ))\n    }","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/tauri-apps/tauri/blob/52e4b6e71d8632a7e648f866c442e287ecddee34/crates/tauri-cli/src/acl/capability/new.rs#L79-L115","documentation":"Panic in the `tauri capability` CLI command. Each --permission string is converted with TryFrom<String> for the ACL Identifier type, which enforces: non-empty, lowercase ASCII alphanumeric/ha hyphen characters, at most one ':' prefix separator (prefix must have a base), no leading/trailing hyphen, no 'tauri-plugin-' start, and a length cap. A string violating those rules aborts capability creation with this panic.","triggerScenarios":"Passing `--permission` values like 'FS:Read' (uppercase), 'fs read' (space), 'fs__read' (underscore), 'core::default' (double separator), 'fs:' (prefix without base), or shell-unquoted arguments that get split.","commonSituations":"Guessing permission names instead of copying canonical ones; uppercase or camelCase identifiers; scripting the CLI with unquoted args; typos in automation.","solutions":["Use canonical lowercase identifiers with a single colon, e.g. `fs:allow-read-text-file`, `core:default`","List available permissions to copy exact names: `tauri permission list`","Quote each --permission argument in shell scripts so spaces/globs cannot mangle it"],"exampleFix":"# before\ntauri capability add media --permission 'FS:Read' --permission fs__read  # panic: invalid permission\n\n# after\ntauri capability add media --permission 'fs:allow-read-file' --permission 'core:default'","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"const VALID_PERMISSION = /^[a-z0-9][a-z0-9-]*(:[a-z0-9][a-z0-9-]*)?$/;\nfunction isPermissionId(p) {\n  return typeof p === 'string'\n    && VALID_PERMISSION.test(p)\n    && !p.startsWith('tauri-plugin-')\n    && !p.endsWith('-')\n    && p.length <= 64;\n}\nisPermissionId('fs:allow-read-file'); // true\nisPermissionId('FS:Read');            // false","tryCatchPattern":null,"preventionTips":["Source permission strings from `tauri permission list` output, never from memory","Validate identifiers in CI scripts before calling the CLI","Quote --permission args to keep shells from splitting them"],"tags":["tauri-cli","capability","acl","permissions","validation"],"backgroundTag":"invalid-permission-identifier","analyzedSha":"52e4b6e71d8632a7e648f866c442e287ecddee34","analyzedAt":"2026-08-20T13:59:20.734Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}