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

  1. Move the `#[from_args(varargs)]` field above all `#[from_args(kw_only)]` fields
  2. If the field should collect keyword arguments instead, change it to `#[from_args(varkwargs)]`, which is allowed after keyword-only fields
  3. 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

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


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