swc-project/swc · error

more than 1 unnamed member field are not allowed

Error message

more than 1 unnamed member field are not allowed

What it means

The Decode derive classifies every non-#[encoding(unknown)] enum variant by shape: named fields map to Struct, exactly one unnamed field maps to One, and no fields maps to Unit. A tuple variant with two or more fields (e.g. Pair(u32, u32)) has no representation in the generated CBOR tag encoding, so macro expansion panics with 'more than 1 unnamed member field are not allowed'. This is a compile-time constraint on the type definition, not a runtime decode failure.

Source

Thrown at crates/ast_node/src/encoding/decode.rs:88

                            #(#fields)*
                            #build_struct
                        };
                        #tail
                        Ok(value)
                    }
                }
            }
        }
        Data::Enum(data) => {
            let enum_type = data.variants.iter().filter(|v| !is_unknown(&v.attrs)).fold(
                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();

View on GitHub (pinned to 5176682b65)

Solutions

  1. Reshape the variant into a named struct variant: `Pair { lo: u32, hi: u32 }`.
  2. Or wrap the payloads in a single struct/newtype: `Pair(RangeFields)`.
  3. Leave two-field tuples to the dedicated #[encoding(unknown)] tag+value variant, which is the only 2-field tuple allowed.

Example fix

// before
#[derive(Encode, Decode)]
enum Bound {
    Pair(u32, u32), // tuple with 2 fields
}

// after — named struct variant
#[derive(Encode, Decode)]
enum Bound {
    Pair { lo: u32, hi: u32 },
}
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Deriving Decode (or #[ast_node] with the encoding-impl feature) on an enum that contains a non-unknown variant with 2+ positional fields, such as `Range(u32, u32)`.

Common situations: Porting serde-style enums (where multi-field tuple variants are idiomatic) into swc AST node types; adding a variant quickly without reshaping it into the supported forms.

Related errors


AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17). Data as JSON: /api/errors/33435a50e807e617. Report an issue: GitHub.