pydantic/monty · error · syn::Error
ToArgs can only be derived for structs with named fields or…
Error message
ToArgs can only be derived for structs with named fields or unit structs
What it means
A compile-time error from the `ToArgs` derive macro. `ToArgs` converts a Rust struct back into Python call arguments, which only makes sense for structs with named fields (or unit structs, which map to zero arguments). Tuple structs and other shapes have no named parameters to emit, so the macro rejects them.
Solutions
- Convert the tuple struct to named fields (e.g. `struct Args { x: i64 }`)
- If no fields are needed, use a unit struct `struct Args;`
- If the type is a tuple wrapper, drop the `ToArgs` derive and convert to arguments manually
Example fix
// before
#[derive(ToArgs)]
struct PointArgs(i64, i64);
// after
#[derive(ToArgs)]
struct PointArgs {
x: i64,
y: i64,
} Defensive patterns
Strategy: validation
Validate before calling
// Only named-field or unit structs support ToArgs.
enum Shape { Named, Unit, Tuple }
fn to_args_supported(shape: Shape) -> bool {
matches!(shape, Shape::Named | Shape::Unit)
} Prevention
- Use named-field structs for anything passed back to Python as arguments
- Do not derive ToArgs on tuple structs
- Reshape tuple wrappers into named structs at the boundary
When it happens
Trigger: Deriving `ToArgs` on a tuple struct (e.g. `struct Args(i64, String)`) or any non-struct data shape accepted by the derive input position.
Common situations: Reusing an existing tuple struct for argument passing, or deriving both `FromArgs` and `ToArgs` on a struct that was recently reshaped into tuple form.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- missing `#[from_args(name = "...")]` on the struct
- only one `#[from_args(varargs)]` field is allowed
- only one `#[from_args(varkwargs)]` field is allowed
- positional-only fields must come before…
- positional-or-keyword fields cannot appear after…
AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13).
Data as JSON: /api/errors/1ea4e4e3658d5ba8.
Report an issue: GitHub.
Appendix: source
Thrown at crates/monty-macros/src/to_args.rs:37
pub(crate) fn expand(input: &DeriveInput) -> syn::Result<TokenStream> {
let DeriveInput {
ident: struct_ident,
data,
..
} = input;
// Unit structs yield an empty vec → trivial impl.
let named_fields: Vec<&syn::Field> = match data {
Data::Struct(DataStruct {
fields: Fields::Named(named),
..
}) => named.named.iter().collect(),
Data::Struct(DataStruct {
fields: Fields::Unit, ..
}) => Vec::new(),
_ => {
return Err(syn::Error::new(
input.span(),
"ToArgs can only be derived for structs with named fields or unit structs",
));
}
};
let mut proj_fields: Vec<ProjField> = Vec::with_capacity(named_fields.len());
let mut seen_varargs = false;
for field in named_fields {
let attrs = parse_field_attrs(&field.attrs)?;
let ident = field.ident.clone().expect("named field");
// Mirror FromArgs' "implicit kw_only after varargs" rule.
let mut kind = attrs.kind;
match kind {
FieldKind::Varargs => seen_varargs = true,
FieldKind::PosOrKeyword if seen_varargs => kind = FieldKind::KwOnly,
_ => {}
}View on GitHub (pinned to adc986b362)