{"record":{"id":"478a064c2ad79781","repo":"DioxusLabs/dioxus","slug":"store-macro-does-not-support-unions","errorCode":null,"errorMessage":"Store macro does not support unions","messagePattern":"Store macro does not support unions","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"packages/stores-macro/src/derive.rs","lineNumber":64,"sourceCode":"    let mut extension_generics = generics.clone();\n    extension_generics.params.insert(0, parse_quote!(__Lens));\n\n    match &input.data {\n        syn::Data::Struct(data_struct) => derive_store_struct(\n            &input,\n            data_struct,\n            extension_trait_name,\n            transposed_name,\n            extension_generics,\n        ),\n        syn::Data::Enum(data_enum) => derive_store_enum(\n            &input,\n            data_enum,\n            extension_trait_name,\n            transposed_name,\n            extension_generics,\n        ),\n        syn::Data::Union(_) => Err(syn::Error::new(\n            input.span(),\n            \"Store macro does not support unions\",\n        )),\n    }\n}\n\n/// Build a constructor expression: `prefix { a, b }`, `prefix(a, b)`, or just `prefix`.\nfn construct_from_fields(prefix: TokenStream2, fields: &Fields, names: &[Ident]) -> TokenStream2 {\n    match fields {\n        Fields::Named(_) => quote! { #prefix { #(#names),* } },\n        Fields::Unnamed(_) => quote! { #prefix(#(#names),*) },\n        Fields::Unit => quote! { #prefix },\n    }\n}\n\n/// Zip original fields with their transposed store types, preserving visibility and names.\nfn zip_transposed_fields(fields: &Fields, types: &[TokenStream2]) -> Vec<TokenStream2> {\n    match fields {","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/DioxusLabs/dioxus/blob/393d190a801ccb441d41923e232289b4f8a5c669/packages/stores-macro/src/derive.rs#L46-L82","documentation":"The #[derive(Store)] macro from dioxus-signals (stores-macro) only implements Store for structs and enums. Rust unions have no field-access discipline the field-tracking store machinery can hook, so the derive refuses unions outright.","triggerScenarios":"Annotating any `union U { a: u32, b: f32 }` declaration with #[derive(Store)].","commonSituations":"FFI/bit-pattern types declared as unions accidentally receiving the derive via a blanket copy-paste; bringing dioxus into an existing crate that models raw memory with unions.","solutions":["Convert the union to an enum or struct (e.g. a tagged enum) and derive Store on that","Wrap the union in a struct, derive Store on the wrapper, and expose union fields through methods","Drop the derive from the union and manage that state without Store"],"exampleFix":"// before\n#[derive(Store)]\nunion Packet { raw: u32, fields: Parts }\n\n// after\nstruct Packet { raw: PacketRepr }\n#[derive(Store)]\nstruct AppState { packet: Packet }","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive Store only on structs and enums; grep for `union` in files carrying the derive","Model unions as tagged enums or struct wrappers when state must live in a Store","Don't blanket-apply dioxus derives with editor snippets across a module"],"tags":["store","derive","proc-macro","union","compile-time"],"backgroundTag":null,"analyzedSha":"393d190a801ccb441d41923e232289b4f8a5c669","analyzedAt":"2026-08-16T11:27:45.815Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}