{"record":{"id":"3c616a4581e9b160","repo":"pydantic/monty","slug":"style-unpack-cannot-be-combined-with-varargs-or-varkwargs-it","errorCode":null,"errorMessage":"`style = unpack` cannot be combined with `varargs` or `varkwargs` — it models a fixed positional min..max range","messagePattern":"`style = unpack` cannot be combined with `varargs` or `varkwargs` — it models a fixed positional min\\.\\.max range","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"crates/monty-macros/src/from_args.rs","lineNumber":232,"sourceCode":"        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) {\n                return err(\n                    \"`at_most_total` cannot be combined with `style = def` or `style = unpack` \\\n                     — the total pre-count models `PyArg_ParseTupleAndKeywords`-family C parsers\",\n                );\n            }\n            if self.varargs_idx.is_some() || self.varkwargs_idx.is_some() {\n                return err(\"`at_most_total` cannot be combined with `varargs` or `varkwargs` \\\n                     — the up-front total-count check is only meaningful for \\\n                     signatures with a fixed maximum\");\n            }","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/pydantic/monty/blob/adc986b362e3961f407868cb118a99fe831b9e61/crates/monty-macros/src/from_args.rs#L214-L250","documentation":"A `#[derive(FromArgs)]` struct with `style = unpack` also declares a `varargs` (`*args`) or `varkwargs` (`**kwargs`) field. `unpack` models `PyArg_UnpackTuple`, a fixed positional min..max range; variadic collection is outside that model, so the macro rejects the combination at compile time.","triggerScenarios":"Compiling `#[derive(FromArgs)] #[from_args(style = \"unpack\")] struct Args { a: i64, #[from_args(varargs)] rest: Vec<Value> }` (or a `varkwargs` field). Checked in `Signature::validate` (crates/monty-macros/src/from_args.rs:231-234).","commonSituations":"Adding a catch-all `*args` field to an existing unpack-style struct while generalizing a builtin; confusing `unpack` (fixed tuple unpack) with general C-style variadic parsing.","solutions":["Remove `style = \"unpack\"` and let the default `clinic` style parse; it supports varargs/varkwargs fields.","If the signature really is fixed-width, drop the varargs/varkwargs field and enumerate the positional fields explicitly with `pos_only`."],"exampleFix":"// before\n#[derive(FromArgs)]\n#[from_args(style = \"unpack\")]\nstruct Args { a: Value, #[from_args(varargs)] rest: Vec<Value> }\n\n// after\n#[derive(FromArgs)]\nstruct Args { a: Value, #[from_args(varargs)] rest: Vec<Value> }","handlingStrategy":"validation","validationCode":"fn unpack_is_fixed_arity(has_varargs: bool, has_varkwargs: bool) -> bool {\n    !has_varargs && !has_varkwargs\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat style = \"unpack\" as strictly fixed min..max positional; variadic fields require another style.","Check the README style table when adding varargs/varkwargs fields to an existing struct."],"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-14T16:17:12.679Z"}