diesel-rs/diesel · error · syn::Error
unexpected token after positional `#[variadic(..)]`
Error message
unexpected token after positional `#[variadic(..)]`
What it means
The `#[variadic(..)]` attribute accepts either a bare integer literal (`#[variadic(3)]`) or a `last_arguments = N` key-value form. If an integer is parsed and any tokens remain inside the parentheses, `parse_attribute` rejects it because a positional count cannot be followed by more content.
Solutions
- Use only the bare count: `#[variadic(3)]`.
- If you need the named form, switch entirely to `#[variadic(last_arguments = 3)]`.
- Remove stray commas or extra tokens after the integer.
Example fix
// before #[sql_function] #[variadic(3, last_arguments = 1)] fn concat_ws(sep: VarChar); // after #[sql_function] #[variadic(last_arguments = 1)] fn concat_ws(sep: VarChar);
Defensive patterns
Strategy: validation
Validate before calling
// Valid variadic forms: // #[variadic(3)] -- positional count only // #[variadic(last_arguments = 3)] -- named form // Anything after the bare integer is invalid.
Prevention
- Never mix the positional and named variadic forms in one attribute.
- Remove trailing commas and stray tokens inside #[variadic(..)].
- Copy an example from diesel tests when unsure of the syntax.
When it happens
Trigger: Writing `#[variadic(3, foo)]`, `#[variadic(3 last_arguments = 1)]`, or trailing commas/tokens after a plain count, inside a `#[sql_function]` attribute.
Common situations: Mixing the positional and named forms in one attribute; typos leaving stray commas or identifiers after the number.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- expect `last_arguments`
- unexpected end of input, expected `=` help: the correct…
- unexpected end of input, expected parentheses help: the…
- , the correct format is `#[aggregate]
- , the correct format is `#[skip_return_type_helper]
AI-assisted analysis of diesel-rs/diesel@6fa6ed01b2 (2026-09-07).
Data as JSON: /api/errors/718c28f43131f599.
Report an issue: GitHub.
Appendix: source
Thrown at diesel_derives/src/sql_function.rs:1411
syn::Error::new(e.span(), format!("{e}, the correct format is `#[window]`"))
})?
.clone(),
restrictions: BackendRestriction::None,
require_order: None,
wrap_macro: None,
},
}),
syn::Meta::List(syn::MetaList {
path,
delimiter: syn::MacroDelimiter::Paren(_),
tokens: _,
}) if path.is_ident("variadic") => {
let (count, flag) = attr
.parse_args_with(|input: syn::parse::ParseStream| {
if input.peek(LitInt){
let count = input.parse::<LitInt>()?;
if !input.is_empty(){
return Err(syn::Error::new(input.span(), "unexpected token after positional `#[variadic(..)]`"));
}
Ok((count, LitBool::new(false, Span::call_site())))
}
else {
let key: Ident = input.parse()?;
if key != "last_arguments" {
return Err(syn::Error::new(key.span(), "expect `last_arguments`"));
}
let _eq: Token![=] = input.parse()?;
let count: LitInt = input.parse()?;
let skip_zero: LitBool = if input.peek(Token![,]) {
let _: Token![,] = input.parse()?;
let key: Ident = input.parse()?;
if key != "skip_zero_argument_variant" {
return Err(
syn::Error::new(
key.span(), "expect `skip_zero_argument_variant`"
)View on GitHub (pinned to 6fa6ed01b2)