{"record":{"id":"0a6d35ed1035359a","repo":"swc-project/swc","slug":"unknown-member-must-be-a-tag-and-a-value","errorCode":null,"errorMessage":"unknown member must be a tag and a value","messagePattern":"unknown member must be a tag and a value","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ast_node/src/encoding/decode.rs","lineNumber":140,"sourceCode":"                                assert_eq!(enum_type, EnumType::Unit);\n                                syn::parse_quote! {\n                                    tag => #ident::#name(tag),\n                                }\n                            }\n                            2 => {\n                                assert_eq!(enum_type, EnumType::One);\n                                let val_ty = &fields.unnamed[1].ty;\n                                syn::parse_quote! {\n                                    tag => {\n                                        let tag: u32 = tag.try_into().map_err(|_| cbor4ii::core::error::DecodeError::CastOverflow {\n                                             name: &\"unknown-tag\",\n                                        })?;\n                                        let val = <#val_ty as cbor4ii::core::dec::Decode<'_>>::decode(reader)?;\n                                        #ident::#name(tag, val)\n                                    },\n                                }\n                            }\n                            _ => panic!(\"unknown member must be a tag and a value\"),\n                        },\n                        _ => panic!(\"named enum unsupported\"),\n                    }\n                });\n\n            if matches!(enum_type, EnumType::Struct) {\n                assert!(\n                    unknown_arm.is_none(),\n                    \"struct enum does not allow unknown variants\"\n                );\n            }\n\n            let mut discriminant: u32 = 0;\n            let fields = iter\n                .map(|field| -> syn::Arm {\n                    match field.discriminant.as_ref() {\n                        Some((_, syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(lit), .. }))) => {\n                            discriminant = lit.base10_parse::<u32>().unwrap();","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/ast_node/src/encoding/decode.rs#L122-L158","documentation":"The #[encoding(unknown)] variant is swc's forward-compatibility escape hatch: unknown CBOR tags on the wire decode into it. The macro only generates code for two shapes — one unnamed field (bare tag: Unknown(u32)) and two unnamed fields (tag + value: Unknown(u32, T), where it decodes fields.unnamed[1]). Any other arity (zero or three-plus unnamed fields) cannot be mapped, so expansion panics with 'unknown member must be a tag and a value'.","triggerScenarios":"Hand-writing derive(Encode/Decode) (not via #[ast_node]) on an enum and annotating a variant #[encoding(unknown)] whose shape is `Unknown`, `Unknown(u32, u32, u32)`, etc.","commonSituations":"Custom AST nodes for swc plugins or swc_ast_unknown builds; hand-porting the auto-generated Unknown variant and getting its arity wrong. #[ast_node] injects the correct Unknown(u32) / Unknown(u32, swc_common::unknown::Unknown) shapes itself, so this fires only for manual derives.","solutions":["Declare the unknown variant with exactly `#[encoding(unknown)] Unknown(u32)` for all-unit enums, or `#[encoding(unknown)] Unknown(u32, YourUnknownType)` for payload-carrying enums.","Prefer #[ast_node(...)] over manual derives so the Unknown variant is generated for you.","Place the unknown variant first — a later assert also requires it to precede tagged variants."],"exampleFix":"// before\n#[derive(Encode, Decode)]\nenum Expr {\n    #[encoding(unknown)]\n    Unknown,\n    Num { value: f64 },\n}\n\n// after — tag + value tuple\n#[derive(Encode, Decode)]\nenum Expr {\n    #[encoding(unknown)]\n    Unknown(u32, swc_common::unknown::Unknown),\n    Num { value: f64 },\n}","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer #[ast_node(...)] over manual Encode/Decode derives so the Unknown variant is generated with the right arity.","If hand-writing, copy the exact shapes: Unknown(u32) for unit enums, Unknown(u32, swc_common::unknown::Unknown) otherwise.","Keep the #[encoding(unknown)] variant first in the enum."],"tags":["rust","proc-macro","derive","decode","enum","unknown-variant"],"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-14T00:17:10.932Z"}