pydantic/monty · error · syn::Error
required positional fields must come before positional field
Error message
required positional fields must come before positional fields with defaults — matching Python signatures, and relied on by the runtime binder's fast path
What it means
A compile-time validation error from the `FromArgs` derive: within positional parameters (pos-only or pos-or-keyword), a required field may not follow a field with a `default`. Python signatures impose the same ordering, and the runtime binder's fast path relies on it to locate required positionals.
Source
Thrown at crates/monty-macros/src/from_args.rs:292
if self.kwarg_error_name.is_some() {
return err("`kwargs_not_supported_yet` cannot be combined with `kwarg_error_name` \
— the override only applies to the unknown-kwarg dispatch path, which is skipped");
}
}
// The runtime binder's fast path fills the first `n` positional slots
// and assumes that satisfies every required positional param — sound
// only if required positional fields precede defaulted ones (the same
// ordering Python enforces for `def` signatures).
let mut seen_positional_default = false;
for field in &self.fields {
if !matches!(field.kind, FieldKind::PosOnly | FieldKind::PosOrKeyword) {
continue;
}
if field.default.is_some() {
seen_positional_default = true;
} else if seen_positional_default {
return Err(syn::Error::new(
field.ident.span(),
"required positional fields must come before positional fields with \
defaults — matching Python signatures, and relied on by the runtime \
binder's fast path",
));
}
}
// Raw binding is deliberately separate from conversion (that split is
// what reproduces CPython's error orderings), so `*args` elements are
// handed over unconverted.
if let Some(idx) = self.varargs_idx
&& !is_vec_of_value(&self.fields[idx].ty)
{
return Err(syn::Error::new(
self.fields[idx].ident.span(),
"`varargs` fields must be `Vec<Value>` — coerce elements in the function body",
));View on GitHub (pinned to adc986b362)
Solutions
- Reorder the struct fields so all required positional fields come first
- Give the later field a `default` if it can be optional
- Mark the defaulted field `kw_only` (with a default, per the binder's constraints) instead of positional
Example fix
// before
#[derive(FromArgs)]
struct Args {
#[from_args(default)]
timeout: u64,
path: String, // required after defaulted — rejected
}
// after
#[derive(FromArgs)]
struct Args {
path: String,
#[from_args(default)]
timeout: u64,
} Defensive patterns
Strategy: validation
Validate before calling
// compile-time convention: keep required positional fields above defaulted ones
struct Args { required1: String, required2: u32, #[from_args(default)] opt: u64 } Prevention
- Order positional fields required-first, defaulted-last, exactly like Python
- After inserting a new field, re-check positional ordering
- Mark optional trailing params kw_only when the call shape allows
When it happens
Trigger: Declaring `#[derive(FromArgs)]` with fields ordered like `a: u32` (default), `b: u32` (required), where both are positional.
Common situations: Alphabetically or accidentally reordering struct fields; inserting a new required parameter after existing defaulted ones; porting a C signature whose ordering the derive cannot mirror.
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
- `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`
- no fields may appear after a `#[from_args(varkwargs)]` field
AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13).
Data as JSON: /api/errors/67f1b7d0284644a5.
Report an issue: GitHub.