pydantic/monty · error · syn::Error
no fields may appear after a `#[from_args(varkwargs)]` field
Error message
no fields may appear after a `#[from_args(varkwargs)]` field
What it means
A compile-time error from the `FromArgs` derive's field-role resolution: `**kwargs` must be the last parameter, mirroring Python, so no struct field may be declared after a `#[from_args(varkwargs)]` field. Any trailing field is rejected at the field's span.
Source
Thrown at crates/monty-macros/src/from_args.rs:555
.filter(|f| !matches!(f.kind, FieldKind::Varargs | FieldKind::Varkwargs))
}
}
/// Second parse pass over the fields: resolve implicit kw_only-after-varargs,
/// enforce declaration ordering, assign positional and slot indices, and
/// locate the `*args` / `**kwargs` fields.
fn resolve_field_roles(fields: &mut [Field]) -> syn::Result<(Option<usize>, Option<usize>)> {
let mut varargs_idx = None;
let mut varkwargs_idx = None;
let mut seen_varargs = false;
let mut seen_varkwargs = false;
let mut seen_pos_or_kw = false;
let mut seen_kw_only = false;
let mut pos_counter: usize = 0;
let mut slot_counter: usize = 0;
for (idx, field) in fields.iter_mut().enumerate() {
if seen_varkwargs {
return Err(syn::Error::new(
field.ident.span(),
"no fields may appear after a `#[from_args(varkwargs)]` field",
));
}
match field.kind {
FieldKind::PosOnly => {
if seen_pos_or_kw || seen_kw_only || seen_varargs {
return Err(syn::Error::new(
field.ident.span(),
"positional-only fields must come before positional-or-keyword, varargs, and keyword-only fields",
));
}
}
FieldKind::PosOrKeyword => {
if seen_varargs {
// Implicit kw_only after varargs.
field.kind = FieldKind::KwOnly;View on GitHub (pinned to adc986b362)
Solutions
- Move the `#[from_args(varkwargs)]` field to be the last field of the struct
- Move the trailing field before the varkwargs field (respecting required-before-default ordering for positionals)
- If the trailing field is really positional, restructure the signature so kwargs remains last
Example fix
// before
#[derive(FromArgs)]
struct Args {
#[from_args(varkwargs)]
options: Vec<(String, Value)>,
name: String, // after varkwargs — rejected
}
// after
#[derive(FromArgs)]
struct Args {
name: String,
#[from_args(varkwargs)]
options: Vec<(String, Value)>,
} Defensive patterns
Strategy: validation
Validate before calling
// varkwargs must be the final field of the struct
struct Args { name: String, #[from_args(varkwargs)] opts: Vec<(String, Value)> } Prevention
- Always declare varkwargs last, mirroring Python signatures
- After any field reorder (alphabetization, IDE sort), verify varkwargs is still last
- Append new parameters before the collector field
When it happens
Trigger: Declaring any field after the one marked `#[from_args(varkwargs)]`, e.g. `#[from_args(varkwargs)] options: ...` followed by `name: String`.
Common situations: Reordering struct fields alphabetically or via an IDE sort; appending a new parameter to the end of the struct without noticing the collector field; porting a Python signature where `**kwargs` is last but the struct drifted.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- FromArgs can only be derived for structs with named fields
- required positional fields must come before positional field
- `varargs` fields must be `Vec<Value>` — coerce elements in t
- keyword-only fields must have a `default` — the runtime bind
- `default` and `static_string` cannot be applied to `varargs`
AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13).
Data as JSON: /api/errors/647992fd017e2317.
Report an issue: GitHub.