{"record":{"id":"347061131dc28213","repo":"leptos-rs/leptos","slug":"expected-named-struct-fields","errorCode":null,"errorMessage":"expected named struct fields","messagePattern":"expected named struct fields","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"leptos_macro/src/params.rs","lineNumber":19,"sourceCode":"use quote::{quote, quote_spanned};\nuse syn::spanned::Spanned;\n\npub fn params_impl(ast: &syn::DeriveInput) -> proc_macro::TokenStream {\n    let name = &ast.ident;\n\n    let fields = if let syn::Data::Struct(syn::DataStruct {\n        fields: syn::Fields::Named(ref fields),\n        ..\n    }) = ast.data\n    {\n        fields\n            .named\n            .iter()\n            .map(|field| {\n\t\t\t\tlet field_name_string = &field\n                    .ident\n                    .as_ref()\n                    .expect(\"expected named struct fields\")\n                    .to_string()\n                    .trim_start_matches(\"r#\")\n                    .to_owned();\n\t\t\t\tlet ident = &field.ident;\n\t\t\t\tlet ty = &field.ty;\n\t\t\t\tlet span = field.span();\n\n\t\t\t\tquote_spanned! {\n\t\t\t\t\tspan=> #ident: ::leptos_router::params::macro_helpers::Wrapper::<#ty>::__into_param(\n                        map.get_str(#field_name_string),\n                        #field_name_string\n                    )?\n\t\t\t\t}\n\t\t\t})\n            .collect()\n    } else {\n        vec![]\n    };","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/leptos-rs/leptos/blob/32d20f6c9d517451d77beb68d88c7716823dac41/leptos_macro/src/params.rs#L1-L37","documentation":"The #[server] (params extraction) macro's params_impl iterates over struct fields and calls field.ident.as_ref().expect(\"expected named struct fields\"). The macro only supports structs with named fields; a unit struct or tuple struct passed to the params derive causes this panic at macro-expansion time.","triggerScenarios":"Applying the params extraction derive/macro to a tuple struct (struct Login(String, String);) or unit struct (struct Login;) instead of a named-field struct.","commonSituations":"Refactoring a named struct into a newtype/tuple struct for convenience; copy-pasting a tuple struct into a server function signature; auto-generated types from schema tools that emit tuple structs.","solutions":["Convert the struct to use named fields: struct Login { username: String, password: String }","If you need a newtype wrapper, extract its inner value into a named struct before passing to the macro","Use a different deserialization approach (manual FromRequestParts) if tuple structs are required"],"exampleFix":"// before\nstruct Login(String, String);\n// after\nstruct Login {\n    username: String,\n    password: String,\n}","handlingStrategy":"validation","validationCode":"// Compile-time guard: named-field structs satisfy the macro; audit types before deriving\nconst _: () = {\n    // unit/tuple structs will fail macro expansion — keep server param structs named-field only\n};","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use only named-field structs with the server params derive","Avoid newtype/tuple structs in server function argument positions","Review refactors that change struct field shape used by server functions","Let the compiler catch it: the panic occurs at macro expansion, so building immediately reveals the offending struct"],"tags":["macro","server-functions","compile-time","derive"],"backgroundTag":"unsupported-struct-shape-for-derive","analyzedSha":"32d20f6c9d517451d77beb68d88c7716823dac41","analyzedAt":"2026-09-01T18:55:42.580Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T01:17:15.007Z"}