pydantic/monty · error · syn::Error
`varargs` cannot appear after keyword-only fields — Python h
Error message
`varargs` cannot appear after keyword-only fields — Python has no signature form with `*args` following keyword-only parameters
What it means
A compile-time error from the `FromArgs` derive macro. A `#[from_args(varargs)]` (`*args`) field must be declared before any keyword-only fields, because no Python signature can place `*args` after keyword-only parameters. The macro mirrors that constraint structurally and rejects the reversed order.
Source
Thrown at crates/monty-macros/src/from_args.rs:595
field.ident.span(),
"positional-or-keyword fields cannot appear after keyword-only fields",
));
} else {
seen_pos_or_kw = true;
}
}
FieldKind::KwOnly => {
seen_kw_only = true;
}
FieldKind::Varargs => {
if seen_varargs {
return Err(syn::Error::new(
field.ident.span(),
"only one `#[from_args(varargs)]` field is allowed",
));
}
if seen_kw_only {
return Err(syn::Error::new(
field.ident.span(),
"`varargs` cannot appear after keyword-only fields — Python has no \
signature form with `*args` following keyword-only parameters",
));
}
seen_varargs = true;
varargs_idx = Some(idx);
}
FieldKind::Varkwargs => {
if seen_varkwargs {
return Err(syn::Error::new(
field.ident.span(),
"only one `#[from_args(varkwargs)]` field is allowed",
));
}
seen_varkwargs = true;
varkwargs_idx = Some(idx);
}View on GitHub (pinned to adc986b362)
Solutions
- Move the `#[from_args(varargs)]` field above all `#[from_args(kw_only)]` fields
- If the field should collect keyword arguments instead, change it to `#[from_args(varkwargs)]`, which is allowed after keyword-only fields
- If the trailing arguments are fixed, drop the varargs attribute and declare normal positional fields before the kw_only block
Example fix
// before
#[derive(FromArgs)]
#[from_args(name = "f"])
struct FArgs {
#[from_args(kw_only)]
flag: bool,
#[from_args(varargs)]
args: Vec<Value>,
}
// after
#[derive(FromArgs)]
#[from_args(name = "f"])
struct FArgs {
#[from_args(varargs)]
args: Vec<Value>,
#[from_args(kw_only)]
flag: bool,
} Defensive patterns
Strategy: validation
Validate before calling
// varargs must precede all kw_only fields.
fn varargs_before_kw_only(kinds: &[&str]) -> bool {
let first_kw_only = kinds.iter().position(|k| *k == "kw_only");
match first_kw_only {
Some(i) => !kinds[i..].contains(&"varargs"),
None => true,
}
} Prevention
- Remember Python's fixed signature order: pos-only, pos-or-kw, *args, kw-only, **kwargs
- Place #[from_args(varargs)] in the middle of the struct, before the kw_only block
- cargo check immediately after reordering fields
When it happens
Trigger: Deriving `FromArgs` on a struct where a `#[from_args(kw_only)]` field appears before a `#[from_args(varargs)]` field.
Common situations: Appending a `*args`-style catch-all to a struct that already ends with keyword-only options; reordering fields and accidentally moving the varargs field below the kw_only block.
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
- positional-only fields must come before positional-or-keywor
- positional-or-keyword fields cannot appear after keyword-onl
- only one `#[from_args(varargs)]` field is allowed
- only one `#[from_args(varkwargs)]` field is allowed
- unknown style `{other}`; expected `def`, `clinic`, `c`, `c_n
AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13).
Data as JSON: /api/errors/844da2a697172501.
Report an issue: GitHub.