{"record":{"id":"6a8f9f5668300a2e","repo":"swc-project/swc","slug":"tag-attribute-must-be-in-form-of-tag","errorCode":null,"errorMessage":"#[tag] attribute must be in form of #[tag(..)]","messagePattern":"#\\[tag\\] attribute must be in form of #\\[tag\\(\\.\\.\\)\\]","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ast_node/src/enum_deserialize.rs","lineNumber":65,"sourceCode":"                        );\n\n                        fields.unnamed.last().unwrap().ty.clone()\n                    }\n                    _ => {\n                        unreachable!(\"#[ast_node] enum cannot contain named fields or unit variant\")\n                    }\n                };\n                let tags = variant\n                    .attrs\n                    .iter()\n                    .filter_map(|attr| -> Option<VariantAttr> {\n                        if !is_attr_name(attr, \"tag\") {\n                            return None;\n                        }\n                        let tokens = match &attr.meta {\n                            Meta::List(meta) => meta.tokens.clone(),\n                            _ => {\n                                panic!(\"#[tag] attribute must be in form of #[tag(..)]\")\n                            }\n                        };\n                        let tags = parse2(tokens).expect(\"failed to parse #[tag] attribute\");\n\n                        Some(tags)\n                    })\n                    .flat_map(|v| v.tags)\n                    .collect::<Punctuated<_, token::Comma>>();\n\n                assert!(\n                    !tags.is_empty(),\n                    \"All #[ast_node] enum variants have one or more tag\"\n                );\n\n                // TODO: Clean up this code\n                if tags.len() == 1\n                    && match tags.first() {\n                        Some(Lit::Str(s)) => &*s.value() == \"*\",","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/ast_node/src/enum_deserialize.rs#L47-L83","documentation":"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(..)].","triggerScenarios":"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.","commonSituations":"Writing custom AST nodes for swc transforms/plugins; IDEs auto-completing serde-style `tag = \"...\"` attributes; copying serde attribute syntax into swc enums.","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."],"exampleFix":"// before\n#[ast_node(\"Ref\")]\nenum Ref {\n    #[tag = \"Super\"]\n    Super(SuperProp),\n}\n\n// after\n#[ast_node(\"Ref\")]\nenum Ref {\n    #[tag(\"Super\")]\n    Super(SuperProp),\n}","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["rust","proc-macro","serde","ast-node","tag-attribute"],"backgroundTag":"macro-attribute-syntax-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"}