pydantic/monty · error · syn::Error
`varargs` fields must be `Vec<Value>` — coerce elements in t
Error message
`varargs` fields must be `Vec<Value>` — coerce elements in the function body
What it means
A compile-time validation error from the `FromArgs` derive: a `#[from_args(varargs)]` field (Python's `*args`) must have type `Vec<Value>`. Elements are bound raw, without conversion, so that CPython's error ordering can be reproduced by coercing in the function body.
Source
Thrown at crates/monty-macros/src/from_args.rs:307
if field.default.is_some() {
seen_positional_default = true;
} else if seen_positional_default {
return Err(syn::Error::new(
field.ident.span(),
"required positional fields must come before positional fields with \
defaults — matching Python signatures, and relied on by the runtime \
binder's fast path",
));
}
}
// Raw binding is deliberately separate from conversion (that split is
// what reproduces CPython's error orderings), so `*args` elements are
// handed over unconverted.
if let Some(idx) = self.varargs_idx
&& !is_vec_of_value(&self.fields[idx].ty)
{
return Err(syn::Error::new(
self.fields[idx].ident.span(),
"`varargs` fields must be `Vec<Value>` — coerce elements in the function body",
));
}
// The runtime binder's fast paths return before the aggregated
// missing-keyword check runs, so a required kw_only slot could slip
// through binding unfilled and later surface `Bound::require`'s
// positional wording. No current signature needs one; reject until
// the fast paths learn to check for them.
if let Some(field) = self
.fields
.iter()
.find(|f| matches!(f.kind, FieldKind::KwOnly) && f.default.is_none())
{
return Err(syn::Error::new(
field.ident.span(),
"keyword-only fields must have a `default` — the runtime binder's fast \View on GitHub (pinned to adc986b362)
Solutions
- Change the field type to `Vec<Value>`
- Coerce each element in the function body after `from_args` (e.g. with `value_to_u64`), raising the appropriate error in CPython's order
- Use fixed named fields with `FromValue` types if element conversion should be automatic
Example fix
// before
#[derive(FromArgs)]
struct Args {
#[from_args(varargs)]
nums: Vec<u64>,
}
// after
#[derive(FromArgs)]
struct Args {
#[from_args(varargs)]
nums: Vec<Value>,
}
// then in body: nums.into_iter().map(|v| value_to_u64(v)).collect::<Result<Vec<_>,_>>() Defensive patterns
Strategy: validation
Validate before calling
#[derive(FromArgs)]
struct Args { #[from_args(varargs)] rest: Vec<Value> } // only legal varargs type Prevention
- Always type varargs fields as Vec<Value>
- Do element coercion in the function body to preserve CPython error ordering
- Treat raw binding as intentional: conversion is a body-level concern
When it happens
Trigger: Declaring a field annotated `#[from_args(varargs)]` with any type other than `Vec<Value>`, e.g. `Vec<String>` or `Vec<u64>`.
Common situations: Trying to make the macro do per-element type conversion for `*args`; copying a `Vec<T>` pattern from a non-varargs field; porting a Rust function signature directly into the args struct.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- FromArgs can only be derived for structs with named fields
- required positional fields must come before positional field
- keyword-only fields must have a `default` — the runtime bind
- `default` and `static_string` cannot be applied to `varargs`
- no fields may appear after a `#[from_args(varkwargs)]` field
AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13).
Data as JSON: /api/errors/ae021266ae9a8213.
Report an issue: GitHub.