tauri-apps/tauri · error · syn::Error

unexpected expression for capability

Error message

unexpected expression for capability

What it means

#[tauri::generate_context] accepts a capabilities = [...] override selecting which capability identifiers are embedded. Each array element must be a string literal, because the macro resolves the names against the project's capabilities at compile time. A const path, macro call, number, or any other expression element fails with 'unexpected expression for capability'.

Source

Thrown at crates/tauri-macros/src/context.rs:80

        }
        Meta::NameValue(v) => {
          let ident = v.path.require_ident()?;
          match ident.to_string().as_str() {
            "capabilities" => {
              if let Expr::Array(array) = v.value {
                capabilities.replace(
                  array
                    .elems
                    .into_iter()
                    .map(|e| {
                      if let Expr::Lit(ExprLit {
                        attrs: _,
                        lit: Lit::Str(s),
                      }) = e
                      {
                        Ok(s.value().into())
                      } else {
                        Err(syn::Error::new(
                          input.span(),
                          "unexpected expression for capability",
                        ))
                      }
                    })
                    .collect::<Result<Vec<_>, syn::Error>>()?,
                );
              } else {
                return Err(syn::Error::new(
                  input.span(),
                  "unexpected value for capabilities",
                ));
              }
            }
            "assets" => {
              assets.replace(v.value);
            }
            "test" => {

View on GitHub (pinned to 52e4b6e71d)

Solutions

  1. Inline every capability as a string literal in the array
  2. If lists must stay in sync, have build.rs write a generated .rs file containing the whole #[tauri::generate_context(...)] invocation with literals and include it
  3. Prefer the default behavior (all capabilities under src-tauri/capabilities are picked up) and drop the override

Example fix

// before
const MAIN_CAPS: &str = "core:default";
#[tauri::generate_context(capabilities = ["core:webview", MAIN_CAPS])]
// after
#[tauri::generate_context(capabilities = ["core:webview", "core:default"])]
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: #[tauri::generate_context(capabilities = ["core:default", MY_CAPS])] where MY_CAPS is a const, or elements like concat!("core:", name) or 42.

Common situations: Trying to DRY capability lists through consts or macros; copying runtime-string patterns into a compile-time attribute; capability names produced by build scripts.

Related errors


AI-assisted analysis of tauri-apps/tauri@52e4b6e71d (2026-08-20). Data as JSON: /api/errors/7ad51727437af8b1. Report an issue: GitHub.