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

only named, wildcard, struct, and tuple struct arguments all

Error message

only named, wildcard, struct, and tuple struct arguments allowed

What it means

The command macro derives each argument's frontend key from the parameter pattern, so only patterns that yield an identifier work: plain identifiers, the wildcard _, struct patterns, and tuple-struct patterns. Everything else — tuple destructuring, references, literals — has no stable key and is rejected with 'only named, wildcard, struct, and tuple struct arguments allowed'.

Source

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

  // we have no use for self arguments
  let mut arg = match arg {
    FnArg::Typed(arg) => arg.pat.as_ref().clone(),
    FnArg::Receiver(arg) => {
      return Err(syn::Error::new(
        arg.span(),
        "unable to use self as a command function parameter",
      ))
    }
  };

  // we only support patterns that allow us to extract some sort of keyed identifier
  let mut key = match &mut arg {
    Pat::Ident(arg) => arg.ident.unraw().to_string(),
    Pat::Wild(_) => "".into(), // we always convert to camelCase, so "_" will end up empty anyways
    Pat::Struct(s) => super::path_to_command(&mut s.path).ident.to_string(),
    Pat::TupleStruct(s) => super::path_to_command(&mut s.path).ident.to_string(),
    err => {
      return Err(syn::Error::new(
        err.span(),
        "only named, wildcard, struct, and tuple struct arguments allowed",
      ))
    }
  };

  // also catch self arguments that use FnArg::Typed syntax
  if key == "self" {
    return Err(syn::Error::new(
      key.span(),
      "unable to use self as a command function parameter",
    ));
  }

  match attributes.argument_case {
    ArgumentCase::Camel => {
      key = key.to_lower_camel_case();
    }

View on GitHub (pinned to 52e4b6e71d)

Solutions

  1. Take the tuple/reference as a single named parameter and destructure in the body
  2. Use tauri's automatic deserialization: a struct parameter gives you named keys on the JS side
  3. Keep patterns to plain idents or _ in command signatures

Example fix

// before
#[tauri::command]
fn resize((w, h): (u32, u32)) { /* ... */ }
// after
#[tauri::command]
fn resize(size: (u32, u32)) {
  let (w, h) = size;
  // JS: invoke('resize', { size: [800, 600] })
}
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: #[tauri::command] fn resize((w, h): (u32, u32)) (Pat::Tuple), fn print(&name: &String) (Pat::Ref), or any destructuring pattern the key-extraction match cannot handle.

Common situations: Writing idiomatic Rust destructuring in command signatures; porting handlers that took tuples; ref parameters borrowed for convenience.

Related errors


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