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
- Take the tuple/reference as a single named parameter and destructure in the body
- Use tauri's automatic deserialization: a struct parameter gives you named keys on the JS side
- 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
- Use plain identifier (or _) parameter patterns in command signatures
- Destructure tuples and references inside the function body
- Model grouped arguments as a struct parameter — tauri deserializes it as named keys
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
- unexpected list input
- expected "camelCase" or "snake_case"
- expected string literal for rename
- unexpected input, expected one of `rename_all`, `rename`, `r
- unable to use self as a command function parameter
AI-assisted analysis of tauri-apps/tauri@52e4b6e71d (2026-08-20).
Data as JSON: /api/errors/d5329e59d03e2044.
Report an issue: GitHub.