swc-project/swc · error
#[tag] attribute must be in form of #[tag(..)]
Error message
#[tag] attribute must be in form of #[tag(..)]
What it means
The DeserializeEnum derive (applied automatically to every #[ast_node(...)] enum) implements untagged serde deserialization by matching the serialized "type" field against per-variant #[tag("...")] attributes. Attribute parsing accepts only the list form (syn::Meta::List); writing `#[tag = "Super"]` (name=value) or a bare `#[tag]` resolves to a different Meta shape and panics at this first expansion pass, with the message stating the exact expected form #[tag(..)].
Source
Thrown at crates/ast_node/src/enum_deserialize.rs:65
);
fields.unnamed.last().unwrap().ty.clone()
}
_ => {
unreachable!("#[ast_node] enum cannot contain named fields or unit variant")
}
};
let tags = variant
.attrs
.iter()
.filter_map(|attr| -> Option<VariantAttr> {
if !is_attr_name(attr, "tag") {
return None;
}
let tokens = match &attr.meta {
Meta::List(meta) => meta.tokens.clone(),
_ => {
panic!("#[tag] attribute must be in form of #[tag(..)]")
}
};
let tags = parse2(tokens).expect("failed to parse #[tag] attribute");
Some(tags)
})
.flat_map(|v| v.tags)
.collect::<Punctuated<_, token::Comma>>();
assert!(
!tags.is_empty(),
"All #[ast_node] enum variants have one or more tag"
);
// TODO: Clean up this code
if tags.len() == 1
&& match tags.first() {
Some(Lit::Str(s)) => &*s.value() == "*",View on GitHub (pinned to 5176682b65)
Solutions
- Use list syntax with string literals: `#[tag("Super")]`; repeat the attribute to give a variant multiple tags.
- Use the wildcard `#[tag("*")]` when one variant should absorb many types.
- Ensure every variant has at least one tag — the very next assert requires it.
Example fix
// before
#[ast_node("Ref")]
enum Ref {
#[tag = "Super"]
Super(SuperProp),
}
// after
#[ast_node("Ref")]
enum Ref {
#[tag("Super")]
Super(SuperProp),
} Defensive patterns
Strategy: validation
Prevention
- Match the documented grammar exactly: #[tag("...")] list form with string literals, never `tag = "..."`.
- Copy working examples from swc_ecma_ast rather than serde attribute docs.
- cargo check the defining crate before depending on it elsewhere in the workspace.
When it happens
Trigger: Defining an enum with #[ast_node("SomeType")] (or #[derive(DeserializeEnum)]) where a variant's tag attribute is `#[tag = "..."]`, a bare `#[tag]`, or any non-parenthesized form.
Common situations: Writing custom AST nodes for swc transforms/plugins; IDEs auto-completing serde-style `tag = "..."` attributes; copying serde attribute syntax into swc enums.
Related errors
- #[ast_serde] on enum does not accept any argument
- unknown attribute: {attr:?}
- An element descriptor's .kind property must be either "metho
- An element descriptor's .placement property must be one of "
- A class descriptor's .kind property must be "class", but a d
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/6a8f9f5668300a2e.
Report an issue: GitHub.