pydantic/monty · error · syn::Error
positional-or-keyword fields cannot appear after keyword-onl
Error message
positional-or-keyword fields cannot appear after keyword-only fields
What it means
A compile-time error from the `FromArgs` derive macro. It fires when a plain positional-or-keyword struct field is declared after a `#[from_args(kw_only)]` field. Since Python signatures place all positional-or-keyword parameters before keyword-only ones, the macro treats the struct field order as the parameter order and rejects the impossible arrangement. (Note: after a `varargs` field the macro silently promotes the field to keyword-only instead of erroring.)
Source
Thrown at crates/monty-macros/src/from_args.rs:576
));
}
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;
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 {View on GitHub (pinned to adc986b362)
Solutions
- Reorder the fields so every positional-or-keyword field comes before all `#[from_args(kw_only)]` fields
- Mark the offending field `#[from_args(kw_only)]` too, if it should be keyword-only
- Remove `#[from_args(kw_only)]` from the earlier field if it should be positional
Example fix
// before
#[derive(FromArgs)]
#[from_args(name = "f"])
struct FArgs {
#[from_args(kw_only)]
flag: bool,
x: i64,
}
// after
#[derive(FromArgs)]
#[from_args(name = "f"])
struct FArgs {
x: i64,
#[from_args(kw_only)]
flag: bool,
} Defensive patterns
Strategy: validation
Validate before calling
// No positional-or-keyword field may follow a kw_only field.
fn pos_or_kw_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..].iter().any(|k| *k == "pos_or_kw"),
None => true,
}
} Prevention
- Order struct fields exactly as the Python signature reads: positional, *args, keyword-only, **kwargs
- Insert new parameters at the signature-correct position, not the end of the struct
- Keep the crates/monty-macros/README.md style table open while writing arg structs
When it happens
Trigger: Deriving `FromArgs` on a struct where at least one field is marked `#[from_args(kw_only)]` and a later field has no kind attribute (positional-or-keyword).
Common situations: Inserting a new parameter in the middle of a struct without noticing a keyword-only field sits above the insertion point; refactoring field order alphabetically or by grouping rather than by signature position.
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
- only one `#[from_args(varargs)]` field is allowed
- `varargs` cannot appear after keyword-only fields — Python h
- 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/2a9c5264730bf90d.
Report an issue: GitHub.