pydantic/monty · error · syn::Error

only one `#[from_args(varargs)]` field is allowed

Error message

only one `#[from_args(varargs)]` field is allowed

What it means

A compile-time error from the `FromArgs` derive macro. Python signatures allow at most one `*args` parameter, so the macro permits at most one field tagged `#[from_args(varargs)]` per struct. A second tagged field cannot be mapped onto a Python signature and is rejected at codegen.

Source

Thrown at crates/monty-macros/src/from_args.rs:589

                if seen_varargs {
                    // Implicit kw_only after varargs.
                    field.kind = FieldKind::KwOnly;
                    seen_kw_only = true;
                } else if seen_kw_only {
                    return Err(syn::Error::new(
                        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(),

View on GitHub (pinned to adc986b362)

Solutions

  1. Keep only one `#[from_args(varargs)]` field and model the extra positional values inside it (e.g. a `Vec<Value>` field)
  2. If the second field has a fixed arity, remove the `varargs` attribute and declare it as a normal positional field
  3. If the second field is truly keyword-based, change it to `#[from_args(kw_only)]` or `#[from_args(varkwargs)]`

Example fix

// before
#[derive(FromArgs)]
#[from_args(name = "f"])
struct FArgs {
    #[from_args(varargs)]
    args: Vec<Value>,
    #[from_args(varargs)]
    more: Vec<Value>,
}

// after
#[derive(FromArgs)]
#[from_args(name = "f"])
struct FArgs {
    #[from_args(varargs)]
    args: Vec<Value>,
}
Defensive patterns

Strategy: validation

Validate before calling

// At most one varargs field per struct.
fn at_most_one(kind: &str, kinds: &[&str]) -> bool {
    kinds.iter().filter(|k| **k == kind).count() <= 1
}

Prevention

When it happens

Trigger: Deriving `FromArgs` on a struct containing two or more fields annotated `#[from_args(varargs)]`.

Common situations: Copy-pasting a varargs field to add a second positional catch-all, or merging two arg structs that each had their own varargs field.

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


AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13). Data as JSON: /api/errors/6eaca8284ca5547f. Report an issue: GitHub.