{"record":{"id":"ecf05865ed78af65","repo":"pydantic/monty","slug":"style-def-cannot-be-combined-with-varargs-a-args-signature","errorCode":null,"errorMessage":"`style = def` cannot be combined with `varargs` — a `*args` signature can never raise too-many-positional, so the style has no effect","messagePattern":"`style = def` cannot be combined with `varargs` — a `\\*args` signature can never raise too-many-positional, so the style has no effect","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"crates/monty-macros/src/from_args.rs","lineNumber":222,"sourceCode":"        signature.validate()?;\n        Ok(signature)\n    }\n\n    /// Style/modifier/field compatibility checks — the single place invalid\n    /// combinations are rejected. Grouped per style, then the orthogonal\n    /// modifiers, so each rule reads as one line of the compatibility table.\n    fn validate(&self) -> syn::Result<()> {\n        let err = |msg: &str| Err(syn::Error::new(self.struct_ident.span(), msg));\n\n        match self.style {\n            Style::Def => {\n                if self.bad_arg.is_some() {\n                    return err(\"`bad_arg`/`bad_arg_named` cannot be combined with `style = def` \\\n                         — CPython `def` binding never type-checks while binding; declare \\\n                         fields as raw `Value` and coerce in the function body\");\n                }\n                if self.varargs_idx.is_some() {\n                    return err(\"`style = def` cannot be combined with `varargs` — a `*args` \\\n                         signature can never raise too-many-positional, so the style has no effect\");\n                }\n            }\n            Style::Unpack => {\n                if self.fields.iter().any(|f| matches!(f.kind, FieldKind::PosOrKeyword)) {\n                    return err(\"`style = unpack` models a positional-only `PyArg_UnpackTuple` \\\n                         signature — every positional field must be `pos_only`\");\n                }\n                if self.varargs_idx.is_some() || self.varkwargs_idx.is_some() {\n                    return err(\"`style = unpack` cannot be combined with `varargs` or `varkwargs` \\\n                         — it models a fixed positional min..max range\");\n                }\n            }\n            Style::Clinic | Style::C | Style::CNamed => {}\n        }\n\n        if self.at_most_total {\n            if matches!(self.style, Style::Def | Style::Unpack) {","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/pydantic/monty/blob/adc986b362e3961f407868cb118a99fe831b9e61/crates/monty-macros/src/from_args.rs#L204-L240","documentation":"A `#[derive(FromArgs)]` struct combines `style = def` with a `*args` (varargs) field. The check rejects it because a signature accepting unlimited positionals can never produce a too-many-positional error — the whole point of the `def` style is to change that error — so the style would silently do nothing. The macro refuses no-op combinations at compile time.","triggerScenarios":"Compiling `#[derive(FromArgs)] #[from_args(style = \"def\")] struct Args { a: i64, #[from_args(varargs)] rest: Vec<Value> }`. Detected in `Signature::validate` when `varargs_idx.is_some()` under `Style::Def` (crates/monty-macros/src/from_args.rs:221-224).","commonSituations":"Writing a variadic helper (like `sum(*args)`) and picking `style = def` while copying the style attribute from a fixed-arity function; refactoring a def-style struct by adding a varargs field without revisiting the style.","solutions":["Remove `style = \"def\"` — with a varargs field the default style already produces the correct behavior since too-many-positional can never occur.","If you truly need def-binding semantics elsewhere, split the struct: a def-style one for fixed params and a separate plain struct for the variadic part."],"exampleFix":"// before\n#[derive(FromArgs)]\n#[from_args(style = \"def\")]\nstruct SumArgs { #[from_args(varargs)] terms: Vec<Value> }\n\n// after\n#[derive(FromArgs)]\nstruct SumArgs { #[from_args(varargs)] terms: Vec<Value> }","handlingStrategy":"validation","validationCode":"// style = \"def\" only has an effect on fixed-arity signatures;\n// skip it whenever the struct declares a varargs field.\nfn should_use_def_style(has_varargs: bool) -> bool { !has_varargs }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only add style attributes that change observable behavior for the given signature shape.","For variadic handlers, use the default style and rely on the runtime binder."],"tags":["rust","proc-macro","fromargs","compile-time"],"backgroundTag":"mutually-exclusive-options","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"}