swc-project/swc · error
unknown member must be a tag and a value
Error message
unknown member must be a tag and a value
What it means
The #[encoding(unknown)] variant is how the generated encoder round-trips unknown CBOR tags. The macro's match on its field count only handles 1 (encode the bare tag) and 2 (encode cbor4ii Tag(tag, value)); any other arity has no meaning, so expansion panics with 'unknown member must be a tag and a value'. #[ast_node] generates the correct shape automatically; this fires for hand-written Encode derives.
Source
Thrown at crates/ast_node/src/encoding/encode.rs:109
);
match &unknown.fields {
syn::Fields::Unnamed(fields) => match fields.unnamed.len() {
1 => {
assert_eq!(enum_type, EnumType::Unit);
syn::parse_quote! {
#ident::#name(tag)
=> tag.encode(writer)?,
}
}
2 => {
assert_eq!(enum_type, EnumType::One);
syn::parse_quote! {
#ident::#name(tag, value)
=> cbor4ii::core::types::Tag((*tag).into(), &*value).encode(writer)?,
}
}
_ => panic!("unknown member must be a tag and a value"),
},
_ => panic!("named enum unsupported"),
}
});
if matches!(enum_type, EnumType::Struct) {
assert!(
unknown_arm.is_none(),
"struct enum does not allow unknown variants"
);
}
let mut discriminant: u32 = 0;
let fields = iter.map(|field| -> syn::Arm {
match field.discriminant.as_ref() {
Some((_, syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(lit), .. }))) => {
discriminant = lit.base10_parse::<u32>().unwrap();
},View on GitHub (pinned to 5176682b65)
Solutions
- Declare it as exactly `#[encoding(unknown)] Unknown(u32)` or `#[encoding(unknown)] Unknown(u32, YourUnknownType)`.
- Prefer #[ast_node(...)] so the Unknown variant is generated correctly.
- Keep the unknown variant first — the macro also asserts it precedes tagged variants.
Example fix
// before
#[derive(Encode, Decode)]
enum Expr {
#[encoding(unknown)]
Unknown(u32, u32, u32),
Num { value: f64 },
}
// after — tag + value tuple
#[derive(Encode, Decode)]
enum Expr {
#[encoding(unknown)]
Unknown(u32, swc_common::unknown::Unknown),
Num { value: f64 },
} Defensive patterns
Strategy: validation
Prevention
- Prefer #[ast_node(...)] over manual Encode/Decode derives so the Unknown variant is generated correctly.
- If hand-writing, use exactly Unknown(u32) or Unknown(u32, swc_common::unknown::Unknown).
- Keep the #[encoding(unknown)] variant first in the enum.
When it happens
Trigger: Hand-writing derive(Encode) (not via #[ast_node]) on an enum with a #[encoding(unknown)] variant of arity 0 or 3+ unnamed fields.
Common situations: Custom AST nodes targeting swc_ast_unknown builds; manually porting the generated Unknown variant with the wrong shape.
Related errors
- named enum unsupported
- unknown member must be a tag and a value
- named enum unsupported
- more than 1 unnamed member field are not allowed
- enum member types must be consistent: {:?}
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/63c10c3e3390c363.
Report an issue: GitHub.