diesel-rs/diesel · error · syn::Error
invalid variadic argument count: not enough function…
Error message
invalid variadic argument count: not enough function arguments
What it means
The `#[sql_function]` / `sql_function!` macro computes how many non-variadic arguments remain by subtracting the variadic argument count from the total declared arguments. If the declared argument count is smaller than the variadic count, the subtraction underflows and this error is raised in `expand_variadic`.
Solutions
- Ensure the total number of function arguments is greater than or equal to the variadic argument count.
- Reduce the `#[variadic(n)]` count to match the actual trailing arguments it should cover.
- Add the missing non-variadic arguments to the function signature.
Example fix
// before #[sql_function] #[variadic(3)] fn concat_ws(sep: VarChar); // only 1 arg, variadic needs 3 // after #[sql_function] #[variadic(3)] fn concat_ws(sep: VarChar, a: VarChar, b: VarChar, c: VarChar); // 1 + 3 args
Defensive patterns
Strategy: validation
Validate before calling
// Verify before compiling: total args must be >= variadic count // #[variadic(N)] requires len(args) >= N const TOTAL_ARGS: usize = 4; const VARIADIC_COUNT: usize = 3; assert!(TOTAL_ARGS >= VARIADIC_COUNT);
Prevention
- Count arguments and the variadic value together whenever you edit a variadic sql_function.
- Remember the variadic count covers only the trailing arguments; leave at least the non-variadic ones in place.
- Re-run cargo check after refactoring function signatures.
When it happens
Trigger: Declaring a SQL function with fewer total arguments than the number given to `#[variadic(N)]` (or `last_arguments = N`), e.g. `#[variadic(3)]` on a function with only 2 arguments.
Common situations: Copy-pasting a variadic function definition and removing arguments without adjusting the variadic count; miscounting which trailing arguments the variadic covers.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- references are not supported in `Queryable` types consider…
- cannot find argument corresponding to the generic
- expect `SQL` as ABI
- expect `SQL` function blocks to be safe
- , the correct format is `#[aggregate]
AI-assisted analysis of diesel-rs/diesel@6fa6ed01b2 (2026-09-07).
Data as JSON: /api/errors/c508e3830c52c7f6.
Report an issue: GitHub.
Appendix: source
Thrown at diesel_derives/src/sql_function.rs:189
mut input: SqlFunctionDecl,
legacy_helper_type_and_module: bool,
generate_return_type_helpers: bool,
variadic_argument_count: usize,
variant_no: usize,
variadic_span: Span,
) -> syn::Result<ExpandedSqlFunction> {
add_variadic_doc_comments(&mut input.attributes, &input.fn_name.to_string());
let sql_name = parse_sql_name_attr(&mut input);
input.fn_name = format_ident!("{}_{}", input.fn_name, variant_no);
let nonvariadic_args_count = input
.args
.len()
.checked_sub(variadic_argument_count)
.ok_or_else(|| {
syn::Error::new(
variadic_span,
"invalid variadic argument count: not enough function arguments",
)
})?;
let mut variadic_generic_indexes = vec![];
let mut arguments_with_generic_types = vec![];
for (arg_idx, arg) in input.args.iter().skip(nonvariadic_args_count).enumerate() {
// If argument is of type that definitely cannot be a generic then we skip it.
let Type::Path(ty_path) = arg.ty.clone() else {
continue;
};
let Ok(ty_ident) = ty_path.path.require_ident() else {
continue;
};
let idx = input.generics.params.iter().position(|param| match param {
GenericParam::Type(type_param) => type_param.ident == *ty_ident,View on GitHub (pinned to 6fa6ed01b2)