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

  1. Use only the bare count: `#[variadic(3)]`.
  2. If you need the named form, switch entirely to `#[variadic(last_arguments = 3)]`.
  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

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.

Related errors


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)