{"record":{"id":"2678886318c8ebcd","repo":"pydantic/monty","slug":"keyword-only-fields-must-have-a-default-the-runtime-binder-s","errorCode":null,"errorMessage":"keyword-only fields must have a `default` — the runtime binder's fast paths skip the aggregated missing-keyword check, so a required keyword-only parameter would report the wrong error; extend the binder before allowing this","messagePattern":"keyword-only fields must have a `default` — the runtime binder's fast paths skip the aggregated missing-keyword check, so a required keyword-only parameter would report the wrong error; extend the binder before allowing this","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"crates/monty-macros/src/from_args.rs","lineNumber":323,"sourceCode":"            && !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            ));\n        }\n\n        // The runtime binder's fast paths return before the aggregated\n        // missing-keyword check runs, so a required kw_only slot could slip\n        // through binding unfilled and later surface `Bound::require`'s\n        // positional wording. No current signature needs one; reject until\n        // the fast paths learn to check for them.\n        if let Some(field) = self\n            .fields\n            .iter()\n            .find(|f| matches!(f.kind, FieldKind::KwOnly) && f.default.is_none())\n        {\n            return Err(syn::Error::new(\n                field.ident.span(),\n                \"keyword-only fields must have a `default` — the runtime binder's fast \\\n                 paths skip the aggregated missing-keyword check, so a required \\\n                 keyword-only parameter would report the wrong error; extend the binder \\\n                 before allowing this\",\n            ));\n        }\n\n        // `default` / `static_string` describe a named parameter slot; on the\n        // collector fields they would be silently dead configuration.\n        for idx in [self.varargs_idx, self.varkwargs_idx].into_iter().flatten() {\n            let field = &self.fields[idx];\n            if field.default.is_some() || field.static_string.is_some() {\n                return Err(syn::Error::new(\n                    field.ident.span(),\n                    \"`default` and `static_string` cannot be applied to `varargs` / \\\n                     `varkwargs` fields — they configure a named parameter slot, which \\\n                     collector fields don't own\",","sourceCodeStart":305,"sourceCodeEnd":341,"githubUrl":"https://github.com/pydantic/monty/blob/adc986b362e3961f407868cb118a99fe831b9e61/crates/monty-macros/src/from_args.rs#L305-L341","documentation":"A compile-time validation error from the `FromArgs` derive: every keyword-only field (`#[from_args(kw_only)]`) must carry a `default`. The runtime binder's fast paths return before any aggregated missing-keyword check, so a required keyword-only parameter would surface as the wrong error (typically a generic missing-argument error).","triggerScenarios":"Declaring a field with `#[from_args(kw_only)]` and no `#[from_args(default = ...)]`, e.g. a required `encoding: String` marked kw_only.","commonSituations":"Porting a CPython function with a required keyword-only parameter (like `open(..., encoding)`); assuming the macro supports required kw-only params because Python does.","solutions":["Add a `default` to the kw-only field and validate emptiness in the body if 'required' semantics are needed","Make the field positional-or-keyword (required positionals are supported) if call-shape allows","Extend the runtime binder's fast paths with an aggregated missing-keyword check before lifting this restriction"],"exampleFix":"// before\n#[derive(FromArgs)]\nstruct OpenArgs {\n    path: String,\n    #[from_args(kw_only)]\n    encoding: String, // required kw-only — rejected\n}\n// after\n#[derive(FromArgs)]\nstruct OpenArgs {\n    path: String,\n    #[from_args(kw_only, default)]\n    encoding: Option<String>, // enforce requirement in the body if needed\n}","handlingStrategy":"validation","validationCode":"// every kw_only field needs a default\n#[from_args(kw_only, default)] encoding: Option<String>","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never declare kw_only without default under the current binder","Enforce 'required kw-only' manually in the function body after from_args","If a truly required kw-only param is needed, extend the binder's fast paths first"],"tags":["rust","proc-macro","compile-time","keyword-arguments"],"backgroundTag":"missing-required-argument","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"}