{"record":{"id":"32a36ccb7957912c","repo":"swc-project/swc","slug":"enum-member-types-must-be-consistent-32a36c","errorCode":null,"errorMessage":"enum member types must be consistent: {:?}","messagePattern":"enum member types must be consistent: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ast_node/src/encoding/encode.rs","lineNumber":73,"sourceCode":"                None,\n                |mut sum, next| {\n                    let ty = match &next.fields {\n                        syn::Fields::Named(_) => EnumType::Struct,\n                        syn::Fields::Unnamed(fields) if fields.unnamed.len() == 1 => EnumType::One,\n                        syn::Fields::Unit => EnumType::Unit,\n                        syn::Fields::Unnamed(_) => {\n                            panic!(\"more than 1 unnamed member field are not allowed\")\n                        }\n                    };\n                    match (*sum.get_or_insert(ty), ty) {\n                        (EnumType::Struct, EnumType::Struct)\n                        | (EnumType::Struct, EnumType::Unit)\n                        | (EnumType::Unit, EnumType::Unit)\n                        | (EnumType::One, EnumType::One) => (),\n                        (EnumType::Unit, EnumType::One)\n                        | (EnumType::One, EnumType::Unit)\n                        | (_, EnumType::Struct) => sum = Some(EnumType::Struct),\n                        _ => panic!(\"enum member types must be consistent: {:?}\", (sum, ty)),\n                    }\n                    sum\n                },\n            );\n            let enum_type = enum_type.expect(\"enum cannot be empty\");\n            let mut iter = data.variants.iter().peekable();\n\n            let unknown_arm: Option<syn::Arm> = iter.next_if(|variant| is_unknown(&variant.attrs))\n                .map(|unknown| {\n                    let name = &unknown.ident;\n                    assert!(\n                        unknown.discriminant.is_none(),\n                        \"unknown member is not allowed custom discriminant\"\n                    );\n                    assert!(\n                        is_with(&unknown.attrs).is_none(),\n                        \"unknown member is not allowed with type\"\n                    );","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/ast_node/src/encoding/encode.rs#L55-L91","documentation":"Encode's derive folds all non-unknown variants into one EnumType (Unit/One/Struct) and requires uniformity. Named-field variants cannot coexist with single-field tuple ('newtype') variants — the (Struct, One) combination falls into the catch-all and panics with the conflicting pair; a Unit+One mix is upgraded to Struct, so Unit+One+One also ends here. The {:?} payload prints the colliding EnumTypes, e.g. (Struct, One).","triggerScenarios":"An enum mixing `A { x: u32 }` (Struct) with `B(u32)` (One) under derive(Encode)/#[ast_node]; or Unit plus multiple One variants, which folds to Struct and then clashes with a later One.","commonSituations":"Incrementally growing an AST enum where later variants use a different style; merging branches that each added variants in different shapes.","solutions":["Make all variants the same shape — usually convert newtype variants to named ones.","Alternatively wrap named payloads in a struct so every variant is single-field.","Read the (X, Y) pair in the panic message to find the disagreeing variant shapes."],"exampleFix":"// before\n#[derive(Encode, Decode)]\nenum Value {\n    Num(f64),                 // One\n    Obj { props: Vec<Prop> }, // Struct — inconsistent\n}\n\n// after — uniform named-struct variants\n#[derive(Encode, Decode)]\nenum Value {\n    Num { value: f64 },\n    Obj { props: Vec<Prop> },\n}","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pick one variant style per enum (all named, or all single-field newtype) and enforce it in review.","Treat the panic's (X, Y) EnumType pair as a pointer to the two disagreeing variants.","cargo check after every variant addition; shape panics surface instantly."],"tags":["rust","proc-macro","derive","encode","enum","cbor"],"backgroundTag":"derive-macro-enum-shape-invalid","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","contentChangedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}