{"record":{"id":"1ea4e4e3658d5ba8","repo":"pydantic/monty","slug":"toargs-can-only-be-derived-for-structs-with-named-fields-or","errorCode":null,"errorMessage":"ToArgs can only be derived for structs with named fields or unit structs","messagePattern":"ToArgs can only be derived for structs with named fields or unit structs","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"crates/monty-macros/src/to_args.rs","lineNumber":37,"sourceCode":"\npub(crate) fn expand(input: &DeriveInput) -> syn::Result<TokenStream> {\n    let DeriveInput {\n        ident: struct_ident,\n        data,\n        ..\n    } = input;\n\n    // Unit structs yield an empty vec → trivial impl.\n    let named_fields: Vec<&syn::Field> = match data {\n        Data::Struct(DataStruct {\n            fields: Fields::Named(named),\n            ..\n        }) => named.named.iter().collect(),\n        Data::Struct(DataStruct {\n            fields: Fields::Unit, ..\n        }) => Vec::new(),\n        _ => {\n            return Err(syn::Error::new(\n                input.span(),\n                \"ToArgs can only be derived for structs with named fields or unit structs\",\n            ));\n        }\n    };\n\n    let mut proj_fields: Vec<ProjField> = Vec::with_capacity(named_fields.len());\n    let mut seen_varargs = false;\n    for field in named_fields {\n        let attrs = parse_field_attrs(&field.attrs)?;\n        let ident = field.ident.clone().expect(\"named field\");\n        // Mirror FromArgs' \"implicit kw_only after varargs\" rule.\n        let mut kind = attrs.kind;\n        match kind {\n            FieldKind::Varargs => seen_varargs = true,\n            FieldKind::PosOrKeyword if seen_varargs => kind = FieldKind::KwOnly,\n            _ => {}\n        }","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/pydantic/monty/blob/adc986b362e3961f407868cb118a99fe831b9e61/crates/monty-macros/src/to_args.rs#L19-L55","documentation":"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.","triggerScenarios":"Deriving `ToArgs` on a tuple struct (e.g. `struct Args(i64, String)`) or any non-struct data shape accepted by the derive input position.","commonSituations":"Reusing an existing tuple struct for argument passing, or deriving both `FromArgs` and `ToArgs` on a struct that was recently reshaped into tuple form.","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"],"exampleFix":"// before\n#[derive(ToArgs)]\nstruct PointArgs(i64, i64);\n\n// after\n#[derive(ToArgs)]\nstruct PointArgs {\n    x: i64,\n    y: i64,\n}","handlingStrategy":"validation","validationCode":"// Only named-field or unit structs support ToArgs.\nenum Shape { Named, Unit, Tuple }\nfn to_args_supported(shape: Shape) -> bool {\n    matches!(shape, Shape::Named | Shape::Unit)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["rust","derive-macro","compile-time","unsupported-type"],"backgroundTag":"unsupported-operation","analyzedSha":"adc986b362e3961f407868cb118a99fe831b9e61","analyzedAt":"2026-09-13T19:19:18.698Z","contentChangedAt":"2026-09-13T19:19:18.698Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}