pydantic/monty · error · syn::Error
`kwargs_not_supported_yet` cannot be combined with `kwarg_er
Error message
`kwargs_not_supported_yet` cannot be combined with `kwarg_error_name` — the override only applies to the unknown-kwarg dispatch path, which is skipped
What it means
This is a compile-time validation error from monty's `#[derive(FromArgs)]` proc macro (in `crates/monty-macros/src/from_args.rs:275`, inside `validate`). A struct declared `kwargs_not_supported_yet` also set `kwarg_error_name`. The flag makes the binder reject every keyword argument up front, which skips the unknown-kwarg dispatch path entirely — so the custom function-name override in `kwarg_error_name` would never be used, and the macro refuses the contradictory combination instead of silently ignoring it.
Source
Thrown at crates/monty-macros/src/from_args.rs:275
if self.kwarg_error_name.is_some() && !matches!(self.style, Style::Def | Style::Clinic | Style::Unpack) {
return err("`kwarg_error_name` is only meaningful with `style = def`, the default \
`clinic` style, or `style = unpack` (where it names the function in the \
`takes no keyword arguments` error) — the C families defer unknown-kwarg \
errors past binding");
}
if self.kwargs_not_supported_yet {
if self.varkwargs_idx.is_some() {
return err("`kwargs_not_supported_yet` cannot be combined with `varkwargs` \
— the flag rejects every kwarg up front, so there's nothing to collect");
}
if self.fields.iter().any(|f| matches!(f.kind, FieldKind::KwOnly)) {
return err("`kwargs_not_supported_yet` cannot be combined with `kw_only` fields \
— the flag rejects every kwarg up front, so kw_only slots are unreachable");
}
if self.kwarg_error_name.is_some() {
return err("`kwargs_not_supported_yet` cannot be combined with `kwarg_error_name` \
— the override only applies to the unknown-kwarg dispatch path, which is skipped");
}
}
// The runtime binder's fast path fills the first `n` positional slots
// and assumes that satisfies every required positional param — sound
// only if required positional fields precede defaulted ones (the same
// ordering Python enforces for `def` signatures).
let mut seen_positional_default = false;
for field in &self.fields {
if !matches!(field.kind, FieldKind::PosOnly | FieldKind::PosOrKeyword) {
continue;
}
if field.default.is_some() {
seen_positional_default = true;
} else if seen_positional_default {
return Err(syn::Error::new(
field.ident.span(),View on GitHub (pinned to adc986b362)
Solutions
- Remove `kwarg_error_name` — `kwargs_not_supported_yet` already rejects all kwargs; the default error message is used.
- Remove `kwargs_not_supported_yet` if you need the custom `takes no keyword arguments` message with the function name; keep `style = unpack` so the unknown-kwarg dispatch path runs and `kwarg_error_name` applies.
- Check `crates/monty-macros/README.md` for which attributes are mutually exclusive and pick the single annotation matching the CPython parser family you are modeling.
Example fix
// before
#[derive(FromArgs)]
#[from_args(name = "normalize", style = unpack, kwargs_not_supported_yet, kwarg_error_name = "normalize")]
struct NormalizeArgs {
#[from_args(pos_only)]
form: StrArg,
}
// after — keep the custom message, drop the eager flag
#[derive(FromArgs)]
#[from_args(name = "normalize", style = unpack, kwarg_error_name = "normalize")]
struct NormalizeArgs {
#[from_args(pos_only)]
form: StrArg,
} Defensive patterns
Strategy: validation
Validate before calling
// Before relying on both attributes, grep the derive input — the macro rejects:
// attrs contains 'kwargs_not_supported_yet' AND attrs contains 'kwarg_error_name'
const conflicting = attrs.includes('kwargs_not_supported_yet') && attrs.includes('kwarg_error_name');
if (conflicting) throw new Error('pick one: eager kwarg rejection or custom kwarg error name'); Prevention
- Read crates/monty-macros/README.md's attribute compatibility table before combining from_args attributes.
- When a compile error appears, trust its explanation — it documents exactly which code path makes the combination unsound.
- Keep one annotation per concern: eager rejection OR custom message, never both.
When it happens
Trigger: Writing `#[from_args(name = "f", kwargs_not_supported_yet, kwarg_error_name = "f")]` (any `kwarg_error_name` value) on a `#[derive(FromArgs)]` struct. It is a compile error at the derive site, not a runtime failure.
Common situations: A developer porting a CPython `PyArg_UnpackTuple`-style function wants the exact `f() takes no keyword arguments` message (via `kwarg_error_name`) and also adds `kwargs_not_supported_yet` to reject kwargs eagerly, not realizing the two annotations target different code paths and cannot coexist.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- FromArgs can only be derived for structs with named fields
- required positional fields must come before positional field
- `varargs` fields must be `Vec<Value>` — coerce elements in t
- keyword-only fields must have a `default` — the runtime bind
- `default` and `static_string` cannot be applied to `varargs`
AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13).
Data as JSON: /api/errors/06f71082255602dc.
Report an issue: GitHub.