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

  1. Ensure `render_param` is only called for PosOnly/PosOrKeyword/KwOnly fields and that varargs/varkwargs fields are filtered out before param rendering
  2. Extend (not shrink) the `FieldKind` match here whenever a new field kind is added, keeping the unreachable arm last
  3. Add a macro-level compile-fail or unit test covering a derive with `#[varargs]`/`#[varkwargs]` fields
  4. 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

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


AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13). Data as JSON: /api/errors/30e8b9c4f0f32232. Report an issue: GitHub.