{"record":{"id":"c3ead5577bf3509f","repo":"pydantic/monty","slug":"at-most-total-cannot-be-combined-with-varargs-or-varkwargs","errorCode":null,"errorMessage":"`at_most_total` cannot be combined with `varargs` or `varkwargs` — the up-front total-count check is only meaningful for signatures with a fixed maximum","messagePattern":"`at_most_total` cannot be combined with `varargs` or `varkwargs` — the up-front total-count check is only meaningful for signatures with a fixed maximum","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"crates/monty-macros/src/from_args.rs","lineNumber":247,"sourceCode":"                         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            }\n        }\n\n        if self.vectorcall && !(self.at_most_total && self.style == Style::Clinic) {\n            return err(\"`vectorcall` requires the default `clinic` style plus `at_most_total` \\\n                 — it models a `tp_vectorcall` fast path in front of a clinic parser\");\n        }\n\n        if self.kwarg_error_name.is_some() && !matches!(self.style, Style::Def | Style::Clinic | Style::Unpack) {\n            return err(\"`kwarg_error_name` is only meaningful with `style = def`, the default \\\n                 `clinic` style, or `style = unpack` (where it names the function in the \\\n                 `takes no keyword arguments` error) — the C families defer unknown-kwarg \\\n                 errors past binding\");\n        }\n\n        if self.kwargs_not_supported_yet {","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/pydantic/monty/blob/adc986b362e3961f407868cb118a99fe831b9e61/crates/monty-macros/src/from_args.rs#L229-L265","documentation":"The `at_most_total` flag was set on a `#[derive(FromArgs)]` struct that also has a `varargs` or `varkwargs` field. The up-front total-count check only makes sense for signatures with a fixed maximum arity; with `*args`/`**kwargs` there is no upper bound to pre-check, so the combination is a compile-time error.","triggerScenarios":"Compiling `#[derive(FromArgs)] #[from_args(at_most_total)] struct Args { a: i64, #[from_args(varargs)] rest: Vec<Value> }` or with a `varkwargs` field. Checked in `Signature::validate` (crates/monty-macros/src/from_args.rs:246-250).","commonSituations":"Generalizing a fixed-arity C-family handler to accept `*args` while leaving the old `at_most_total` flag; mixing attributes from two structs with different shapes.","solutions":["Remove `at_most_total` from the struct.","If you need the pre-count check, drop the varargs/varkwargs field and give the struct a fixed set of fields.","If a cap on the number of arguments is truly needed, enforce it manually in the function body after collection."],"exampleFix":"// before\n#[derive(FromArgs)]\n#[from_args(at_most_total)]\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 at_most_total_needs_fixed_max(has_varargs: bool, has_varkwargs: bool) -> bool {\n    !has_varargs && !has_varkwargs\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["A pre-count check needs an upper bound; any struct with *args/**kwargs cannot have one.","If a cap is needed on variadic input, enforce it in the function body."],"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"}