swc-project/swc · error
enum member types must be consistent: {:?}
Error message
enum member types must be consistent: {:?} What it means
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).
Source
Thrown at crates/ast_node/src/encoding/encode.rs:73
None,
|mut sum, next| {
let ty = match &next.fields {
syn::Fields::Named(_) => EnumType::Struct,
syn::Fields::Unnamed(fields) if fields.unnamed.len() == 1 => EnumType::One,
syn::Fields::Unit => EnumType::Unit,
syn::Fields::Unnamed(_) => {
panic!("more than 1 unnamed member field are not allowed")
}
};
match (*sum.get_or_insert(ty), ty) {
(EnumType::Struct, EnumType::Struct)
| (EnumType::Struct, EnumType::Unit)
| (EnumType::Unit, EnumType::Unit)
| (EnumType::One, EnumType::One) => (),
(EnumType::Unit, EnumType::One)
| (EnumType::One, EnumType::Unit)
| (_, EnumType::Struct) => sum = Some(EnumType::Struct),
_ => panic!("enum member types must be consistent: {:?}", (sum, ty)),
}
sum
},
);
let enum_type = enum_type.expect("enum cannot be empty");
let mut iter = data.variants.iter().peekable();
let unknown_arm: Option<syn::Arm> = iter.next_if(|variant| is_unknown(&variant.attrs))
.map(|unknown| {
let name = &unknown.ident;
assert!(
unknown.discriminant.is_none(),
"unknown member is not allowed custom discriminant"
);
assert!(
is_with(&unknown.attrs).is_none(),
"unknown member is not allowed with type"
);View on GitHub (pinned to 5176682b65)
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.
Example fix
// before
#[derive(Encode, Decode)]
enum Value {
Num(f64), // One
Obj { props: Vec<Prop> }, // Struct — inconsistent
}
// after — uniform named-struct variants
#[derive(Encode, Decode)]
enum Value {
Num { value: f64 },
Obj { props: Vec<Prop> },
} Defensive patterns
Strategy: validation
Prevention
- 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.
When it happens
Trigger: 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.
Common situations: Incrementally growing an AST enum where later variants use a different style; merging branches that each added variants in different shapes.
Related errors
- more than 1 unnamed member field are not allowed
- more than 1 unnamed member field are not allowed
- enum member types must be consistent: {:?}
- unknown member must be a tag and a value
- named enum unsupported
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/32a36ccb7957912c.
Report an issue: GitHub.