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

unexpected input, expected one of `rename_all`, `rename`, `r

Error message

unexpected input, expected one of `rename_all`, `rename`, `root`, `async`

What it means

When a #[tauri::command] attribute item parses as a bare path (a single word with no = value and no parentheses), the macro hits the Meta::Path branch. Only the bare word async is meaningful (WrapperAttributeKind::Async, switching the executor); every other bare token is rejected with 'unexpected input, expected one of rename_all, rename, root, async'.

Source

Thrown at crates/tauri-macros/src/command/wrapper.rs:110

          } else if v.path.is_ident("root") {
            if let Expr::Lit(ExprLit {
              lit: Lit::Str(s),
              attrs: _,
            }) = v.value
            {
              let lit = s.value();

              wrapper_attributes.root = if lit == "crate" {
                quote!($crate)
              } else {
                let ident = Ident::new(&lit, Span::call_site());
                quote!(#ident)
              };
            }
          }
        }
        WrapperAttributeKind::Meta(Meta::Path(_)) => {
          return Err(syn::Error::new(
            input.span(),
            "unexpected input, expected one of `rename_all`, `rename`, `root`, `async`",
          ));
        }
        WrapperAttributeKind::Async => {
          wrapper_attributes.execution_context = ExecutionContext::Async;
        }
      }
    }

    Ok(wrapper_attributes)
  }
}

/// The execution context of the command.
enum ExecutionContext {
  Async,
  Blocking,

View on GitHub (pinned to 52e4b6e71d)

Solutions

  1. Give every key a value: #[tauri::command(rename_all = "camelCase")]
  2. For async commands use the exact bare flag: #[tauri::command(async)]
  3. Remove unsupported flags; the vocabulary is exactly rename_all, rename, root, async

Example fix

// before
#[tauri::command(rename_all)]
fn save(file_path: String) {}
// after
#[tauri::command(rename_all = "camelCase")]
fn save(file_path: String) {} // JS: invoke('save', { filePath })
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: #[tauri::command(rename_all)] (missing = "snake_case"), #[tauri::command(my_flag)], or any identifier written without a value. Async commands must use the exact bare word: #[tauri::command(async)].

Common situations: Forgetting the = value after a key; assuming boolean flags exist (there are none besides async); typos in key names turning them into unknown bare paths.

Related errors


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