{"record":{"id":"cd989d65b885d2b3","repo":"swc-project/swc","slug":"an-element-descriptor-s-kind-property-must-be-eit","errorCode":null,"errorMessage":"An element descriptor's .kind property must be either \"method\" or \"field\", but a decorator created an element descriptor with .kind \"${kind}\"","messagePattern":"An element descriptor's \\.kind property must be either \"method\" or \"field\", but a decorator created an element descriptor with \\.kind \"(.+?)\"","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"crates/swc_ecma_transforms_base/src/helpers/generated/_decorate.rs","lineNumber":196,"sourceCode":"    if (element.kind === \"field\") obj.initializer = element.initializer;\n\n    return obj;\n}\nfunction _toElementDescriptors(elementObjects) {\n    if (elementObjects === undefined) return;\n\n    return _to_array(elementObjects).map(function(elementObject) {\n        var element = _toElementDescriptor(elementObject);\n        _disallowProperty(elementObject, \"finisher\", \"An element descriptor\");\n        _disallowProperty(elementObject, \"extras\", \"An element descriptor\");\n\n        return element;\n    });\n}\nfunction _toElementDescriptor(elementObject) {\n    var kind = String(elementObject.kind);\n    if (kind !== \"method\" && kind !== \"field\") {\n        throw new TypeError(\"An element descriptor's .kind property must be either \\\"method\\\" or\" + \" \\\"field\\\", but a decorator created an element descriptor with\" + \" .kind \\\"\" + kind + \"\\\"\");\n    }\n    var key = _to_property_key(elementObject.key);\n    var placement = String(elementObject.placement);\n    if (placement !== \"static\" && placement !== \"prototype\" && placement !== \"own\") {\n        throw new TypeError(\n            \"An element descriptor's .placement property must be one of \\\"static\\\",\"\n                + \" \\\"prototype\\\" or \\\"own\\\", but a decorator created an element descriptor\"\n                + \" with .placement \\\"\"\n                + placement\n                + \"\\\"\"\n        );\n    }\n    var descriptor = elementObject.descriptor;\n    _disallowProperty(elementObject, \"elements\", \"An element descriptor\");\n    var element = { kind: kind, key: key, placement: placement, descriptor: Object.assign({}, descriptor) };\n    if (kind !== \"field\") _disallowProperty(elementObject, \"initializer\", \"A method descriptor\");\n    else {\n        _disallowProperty(descriptor, \"get\", \"The property descriptor of a field descriptor\");","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_ecma_transforms_base/src/helpers/generated/_decorate.rs#L178-L214","documentation":"The #[derive(Decode)] macro from the ast_node crate folds over the enum's variants to determine the overall EnumType (Unit/One/Struct). With zero variants the fold never produces a value, so enum_type.expect(\"enum cannot be empty\") panics during compilation. This is a proc-macro panic: the compiler aborts with 'proc-macro panicked' and this message, pointing at the derive.","triggerScenarios":"Applying #[derive(Decode)] (or the encoding derives) from swc's ast_node crate to an enum with no variants, e.g. `#[derive(Decode)] enum Never {}`. The mirror-image code in encode.rs fails identically for #[derive(Encode)].","commonSituations":"Writing `enum State {}` as a placeholder for a future state machine; refactoring that temporarily empties an enum while the derive stays attached; codegen that emits enums driven by external schemas which can produce zero cases.","solutions":["Add at least one variant to the enum so the fold can infer the enum type, e.g. a placeholder unit or newtype variant.","If the type is intentionally uninhabited, remove the Decode/Encode derive and hand-implement or gate the type withPhantomData-based never types instead.","Keep the assert message in mind: 'enum cannot be empty' refers to variant count, not to a missing field."],"exampleFix":"// before: empty enum -> proc macro panic 'enum cannot be empty'\n#[derive(Decode, Encode)]\nenum Phase {}\n\n// after: give it at least one variant\n#[derive(Decode, Encode)]\nenum Phase {\n    Start(u32),\n}","handlingStrategy":"validation","validationCode":"// There is no runtime API to guard - guard at authoring time.\n// Quick check: refuse to derive on empty enums in code review or a lint:\n// (clippy) empty enums used only as never-types should not carry AST derives.\n// Compile-time canary so an emptied enum fails loudly in tests, not in prod builds:\n#[test]\nfn ast_enum_derives_compile() {\n    #[derive(swc_ast_node::Decode, swc_ast_node::Encode)]\n    enum Sample {\n        A(u8),\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never leave placeholder `enum X {}` declarations with derives attached - either fill in a variant or remove the derive.","If schema codegen can emit zero-case enums, generate the derive only when variants.len() > 0."],"tags":["rust","proc-macro","derive","swc","compile-time","enum"],"backgroundTag":"empty-enum-derive","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","contentChangedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}