{"record":{"id":"30e8b9c4f0f32232","repo":"pydantic/monty","slug":"varargs-varkwargs-own-no-param-slot","errorCode":null,"errorMessage":"varargs/varkwargs own no param slot","messagePattern":"varargs/varkwargs own no param slot","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/monty-macros/src/from_args.rs","lineNumber":665,"sourceCode":"        },\n    }\n}\n\nimpl Field {\n    /// The `Param` literal for the runtime spec. `never_matchable` (the\n    /// struct's `kwargs_not_supported_yet`) forces `kwarg_id: None`.\n    fn render_param(&self, never_matchable: bool) -> TokenStream {\n        let name = self.ident.to_string();\n        let kwarg_id = if never_matchable {\n            quote! { ::std::option::Option::None }\n        } else {\n            self.kwarg_id_expr()\n        };\n        let kind = match self.kind {\n            FieldKind::PosOnly => quote! { crate::args::ParamKind::PosOnly },\n            FieldKind::PosOrKeyword => quote! { crate::args::ParamKind::PosOrKeyword },\n            FieldKind::KwOnly => quote! { crate::args::ParamKind::KwOnly },\n            FieldKind::Varargs | FieldKind::Varkwargs => unreachable!(\"varargs/varkwargs own no param slot\"),\n        };\n        let required = self.default.is_none();\n        quote! {\n            crate::args::Param {\n                name: #name,\n                kwarg_id: #kwarg_id,\n                kind: #kind,\n                required: #required,\n            }\n        }\n    }\n\n    /// `Option<StringId>` expression for kwarg matching. Single-char ASCII\n    /// field names use the `StringId::from_ascii` fast path (they aren't\n    /// `StaticStrings` variants); plain `pos_only` fields without a\n    /// `static_string` override get `None` — not matchable by keyword, so a\n    /// kwarg with their name falls through to unknown-kwarg handling rather\n    /// than the \"positional-only passed as keyword\" error.","sourceCodeStart":647,"sourceCodeEnd":683,"githubUrl":"https://github.com/pydantic/monty/blob/adc986b362e3961f407868cb118a99fe831b9e61/crates/monty-macros/src/from_args.rs#L647-L683","documentation":"This `unreachable!()` in the `#[derive(FromArgs)]` code generator (monty-macros, `render_param`) asserts that `*args`/`**kwargs` fields (`FieldKind::Varargs`/`Varkwargs`) never generate a `crate::args::Param` slot — they are consumed by the binder's varargs/varkwargs machinery instead of appearing in the positional/keyword parameter spec. Firing means the derive emitted a param entry for a varargs/varkwargs field, i.e. a bug in the macro's field-kind dispatch. It cannot fire from user code using `#[derive(FromArgs)]` correctly.","triggerScenarios":"Only when editing `crates/monty-macros/src/from_args.rs`: adding a new `FieldKind` variant that maps to Varargs/Varkwargs but falls through to `render_param`, or restructuring the match so varargs fields reach param rendering.","commonSituations":"Encountered while extending the `FromArgs` attribute surface (new styles like `varargs`/`unpack`), or renaming/moving `FieldKind` variants so a match arm was dropped.","solutions":["Ensure `render_param` is only called for PosOnly/PosOrKeyword/KwOnly fields and that varargs/varkwargs fields are filtered out before param rendering","Extend (not shrink) the `FieldKind` match here whenever a new field kind is added, keeping the unreachable arm last","Add a macro-level compile-fail or unit test covering a derive with `#[varargs]`/`#[varkwargs]` fields","Run `cargo test -p monty-monty-macros` and `make test` on a derive-using crate"],"exampleFix":"// before\nlet kind = match self.kind {\n    FieldKind::PosOnly => quote! { crate::args::ParamKind::PosOnly },\n    FieldKind::Varargs | FieldKind::Varkwargs => unreachable!(\"varargs/varkwargs own no param slot\"),\n};\n// after\nlet kind = match self.kind {\n    FieldKind::PosOnly => quote! { crate::args::ParamKind::PosOnly },\n    FieldKind::Varargs | FieldKind::Varkwargs => return Ok(None), // handled by binder, no slot\n};","handlingStrategy":"validation","validationCode":"// Macro-time check before rendering params\nassert!(\n    !matches!(field.kind, FieldKind::Varargs | FieldKind::Varkwargs),\n    \"render_param must not be called for varargs/varkwargs fields\"\n);","typeGuard":"fn takes_param_slot(kind: &FieldKind) -> bool {\n    matches!(kind, FieldKind::PosOnly | FieldKind::PosOrKeyword | FieldKind::KwOnly)\n}","tryCatchPattern":"// N/A — compile-time codegen; guard at macro expansion instead of catching a runtime panic","preventionTips":["Filter varargs/varkwargs fields out before the param-rendering loop in the derive","Add compile-fail/UI tests for derives using `#[varargs]` and `#[varkwargs]`","When adding a `FieldKind` variant, grep for every `match self.kind` in the macro and update all of them","Keep the exhaustive match (no `_` arm) so the compiler forces updates"],"tags":["rust","proc-macro","codegen","internal-assert"],"backgroundTag":"internal-invariant-violation","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"}