pydantic/monty · error
varargs/varkwargs own no param slot
Error message
varargs/varkwargs own no param slot
What it means
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.
Source
Thrown at crates/monty-macros/src/from_args.rs:665
},
}
}
impl Field {
/// The `Param` literal for the runtime spec. `never_matchable` (the
/// struct's `kwargs_not_supported_yet`) forces `kwarg_id: None`.
fn render_param(&self, never_matchable: bool) -> TokenStream {
let name = self.ident.to_string();
let kwarg_id = if never_matchable {
quote! { ::std::option::Option::None }
} else {
self.kwarg_id_expr()
};
let kind = match self.kind {
FieldKind::PosOnly => quote! { crate::args::ParamKind::PosOnly },
FieldKind::PosOrKeyword => quote! { crate::args::ParamKind::PosOrKeyword },
FieldKind::KwOnly => quote! { crate::args::ParamKind::KwOnly },
FieldKind::Varargs | FieldKind::Varkwargs => unreachable!("varargs/varkwargs own no param slot"),
};
let required = self.default.is_none();
quote! {
crate::args::Param {
name: #name,
kwarg_id: #kwarg_id,
kind: #kind,
required: #required,
}
}
}
/// `Option<StringId>` expression for kwarg matching. Single-char ASCII
/// field names use the `StringId::from_ascii` fast path (they aren't
/// `StaticStrings` variants); plain `pos_only` fields without a
/// `static_string` override get `None` — not matchable by keyword, so a
/// kwarg with their name falls through to unknown-kwarg handling rather
/// than the "positional-only passed as keyword" error.View on GitHub (pinned to adc986b362)
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
Example fix
// before
let kind = match self.kind {
FieldKind::PosOnly => quote! { crate::args::ParamKind::PosOnly },
FieldKind::Varargs | FieldKind::Varkwargs => unreachable!("varargs/varkwargs own no param slot"),
};
// after
let kind = match self.kind {
FieldKind::PosOnly => quote! { crate::args::ParamKind::PosOnly },
FieldKind::Varargs | FieldKind::Varkwargs => return Ok(None), // handled by binder, no slot
}; Defensive patterns
Strategy: validation
Validate before calling
// Macro-time check before rendering params
assert!(
!matches!(field.kind, FieldKind::Varargs | FieldKind::Varkwargs),
"render_param must not be called for varargs/varkwargs fields"
); Type guard
fn takes_param_slot(kind: &FieldKind) -> bool {
matches!(kind, FieldKind::PosOnly | FieldKind::PosOrKeyword | FieldKind::KwOnly)
} Try / catch
// N/A — compile-time codegen; guard at macro expansion instead of catching a runtime panic
Prevention
- 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
When it happens
Trigger: 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.
Common situations: Encountered while extending the `FromArgs` attribute surface (new styles like `varargs`/`unpack`), or renaming/moving `FieldKind` variants so a match arm was dropped.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- checked above
- ObjectList is decode-only
- PairList is decode-only
- TypeBody is decode-only
- NamedTupleBody is decode-only
AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13).
Data as JSON: /api/errors/30e8b9c4f0f32232.
Report an issue: GitHub.