{"record":{"id":"67f1b7d0284644a5","repo":"pydantic/monty","slug":"required-positional-fields-must-come-before-positional","errorCode":null,"errorMessage":"required positional fields must come before positional fields with defaults — matching Python signatures, and relied on by the runtime binder's fast path","messagePattern":"required positional fields must come before positional fields with defaults — matching Python signatures, and relied on by the runtime binder's fast path","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"crates/monty-macros/src/from_args.rs","lineNumber":292,"sourceCode":"            if self.kwarg_error_name.is_some() {\n                return err(\"`kwargs_not_supported_yet` cannot be combined with `kwarg_error_name` \\\n                     — the override only applies to the unknown-kwarg dispatch path, which is skipped\");\n            }\n        }\n\n        // The runtime binder's fast path fills the first `n` positional slots\n        // and assumes that satisfies every required positional param — sound\n        // only if required positional fields precede defaulted ones (the same\n        // ordering Python enforces for `def` signatures).\n        let mut seen_positional_default = false;\n        for field in &self.fields {\n            if !matches!(field.kind, FieldKind::PosOnly | FieldKind::PosOrKeyword) {\n                continue;\n            }\n            if field.default.is_some() {\n                seen_positional_default = true;\n            } else if seen_positional_default {\n                return Err(syn::Error::new(\n                    field.ident.span(),\n                    \"required positional fields must come before positional fields with \\\n                     defaults — matching Python signatures, and relied on by the runtime \\\n                     binder's fast path\",\n                ));\n            }\n        }\n\n        // Raw binding is deliberately separate from conversion (that split is\n        // what reproduces CPython's error orderings), so `*args` elements are\n        // handed over unconverted.\n        if let Some(idx) = self.varargs_idx\n            && !is_vec_of_value(&self.fields[idx].ty)\n        {\n            return Err(syn::Error::new(\n                self.fields[idx].ident.span(),\n                \"`varargs` fields must be `Vec<Value>` — coerce elements in the function body\",\n            ));","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/pydantic/monty/blob/adc986b362e3961f407868cb118a99fe831b9e61/crates/monty-macros/src/from_args.rs#L274-L310","documentation":"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.","triggerScenarios":"Declaring `#[derive(FromArgs)]` with fields ordered like `a: u32` (default), `b: u32` (required), where both are positional.","commonSituations":"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.","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"],"exampleFix":"// before\n#[derive(FromArgs)]\nstruct Args {\n    #[from_args(default)]\n    timeout: u64,\n    path: String, // required after defaulted — rejected\n}\n// after\n#[derive(FromArgs)]\nstruct Args {\n    path: String,\n    #[from_args(default)]\n    timeout: u64,\n}","handlingStrategy":"validation","validationCode":"// compile-time convention: keep required positional fields above defaulted ones\nstruct Args { required1: String, required2: u32, #[from_args(default)] opt: u64 }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["rust","proc-macro","compile-time","python-signatures"],"backgroundTag":"schema-validation-failed","analyzedSha":"adc986b362e3961f407868cb118a99fe831b9e61","analyzedAt":"2026-09-13T19:19:18.698Z","contentChangedAt":"2026-09-13T19:19:18.698Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}