diesel-rs/diesel · error · syn::Error

expect `skip_zero_argument_variant`

Error message

expect `skip_zero_argument_variant`

What it means

This error comes from diesel's `#[sql_function]` proc macro when parsing the `#[variadic(last_arguments = N, skip_zero_argument_variant = ...)]` attribute. After `last_arguments = N`, an optional second key may be given, but the parser found an identifier other than `skip_zero_argument_variant`. The macro aborts compilation because the attribute syntax is not recognized.

Solutions

  1. Rename the second attribute key to exactly `skip_zero_argument_variant`
  2. Remove the second key entirely, leaving only `#[variadic(last_arguments = N)]`
  3. Check the diesel version's docs for the exact accepted variadic attribute syntax

Example fix

// before
#[variadic(last_arguments = 2, skip_zero = true)]
// after
#[variadic(last_arguments = 2, skip_zero_argument_variant = true)]
Defensive patterns

Strategy: validation

Validate before calling

fn check_variadic_attr(attr: &str) -> Result<(), String> {
    let inner = attr.trim_start_matches("variadic(").trim_end_matches(')');
    let parts: Vec<&str> = inner.split(',').map(|s| s.trim()).collect();
    if !parts[0].starts_with("last_arguments =") { return Err(format!("bad key: {}", parts[0])); }
    if let Some(p) = parts.get(1) {
        if !p.starts_with("skip_zero_argument_variant =") {
            return Err(format!("second key must be skip_zero_argument_variant, got: {}", p));
        }
    }
    Ok(())
}

Type guard

fn is_valid_variadic_second_key(key: &str) -> bool { key == "skip_zero_argument_variant" }

Prevention

When it happens

Trigger: Using `#[sql_function]` with a `#[variadic(last_arguments = N, <wrong_key> = ...)]` attribute where the second key is misspelled or not `skip_zero_argument_variant` (e.g. `skip_zero`, `skip_zero_args`).

Common situations: Typos when copying the variadic attribute syntax from docs or other crates; renaming the option in custom code; mixing up diesel versions with different attribute spellings.

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/1573e1c73dd6eab3. Report an issue: GitHub.

Appendix: source

Thrown at diesel_derives/src/sql_function.rs:1427

                        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`"
                                    )
                                );
                            }
                            let _eq: Token![=] = input.parse()?;
                            input.parse()?
                        } else {
                            LitBool::new(false, Span::call_site())
                        };
                        Ok((count, skip_zero))
                    }
                })
                .map_err(|e| {
                    syn::Error::new(
                        e.span(),
                        format!(
                            "{e}, the correct format is `#[variadic(last_arguments = 3)]` or `#[variadic(last_arguments = 3, skip_zero_argument_variant = true)]`"
                        ),

View on GitHub (pinned to 6fa6ed01b2)