{"record":{"id":"e59328a109055dcc","repo":"swc-project/swc","slug":"an-element-descriptor-s-placement-property-must-b","errorCode":null,"errorMessage":"An element descriptor's .placement property must be one of \"static\", \"prototype\" or \"own\", but a decorator created an element descriptor with .placement \"${placement}\"","messagePattern":"An element descriptor's \\.placement property must be one of \"static\", \"prototype\" or \"own\", but a decorator created an element descriptor with \\.placement \"(.+?)\"","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"crates/swc_ecma_transforms_base/src/helpers/generated/_decorate.rs","lineNumber":201,"sourceCode":"    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\");\n        _disallowProperty(descriptor, \"set\", \"The property descriptor of a field descriptor\");\n        _disallowProperty(descriptor, \"value\", \"The property descriptor of a field descriptor\");\n        element.initializer = elementObject.initializer;\n    }\n","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_ecma_transforms_base/src/helpers/generated/_decorate.rs#L183-L219","documentation":"The #[derive(Encode)] macro from swc's ast_node crate computes a single EnumType across all variants by folding. If the enum has no variants, the fold yields None and enum_type.expect(\"enum cannot be empty\") panics inside the proc macro at compile time. The compiler reports 'proc-macro panicked' with this message attached to the derive invocation.","triggerScenarios":"Deriving Encode (or the paired Decode) on a variant-less enum: `#[derive(Encode)] enum Void {}`. Also reachable when a macro/codegen layer forwards an emptied enum into these derives.","commonSituations":"Placeholder types committed before variants are written; schema-driven codegen where an empty category is legal in the schema but not for these derives; refactors that move all variants elsewhere and leave the shell behind with derives intact.","solutions":["Add a variant (unit or single-field) so the enum type inference has input.","Remove the Encode/Decode derive from intentionally empty enums.","If the empty enum models 'never', consider a struct with an uninhabited field or simply drop the type from the serialized AST."],"exampleFix":"// before: panics with 'enum cannot be empty'\n#[derive(Encode, Decode)]\nenum NoCases {}\n\n// after\n#[derive(Encode, Decode)]\nenum NoCases {\n    #[encoding(ignore)]\n    Placeholder(u8),\n}","handlingStrategy":"validation","validationCode":"// Codegen guard: only emit derives when the enum is non-empty.\nlet variants = schema.cases; // your generator's variant list\nlet derive_attr = if variants.is_empty() {\n    String::new()\n} else {\n    \"#[derive(Encode, Decode)]\".to_string()\n};\n// then: #{derive_attr} enum {name} { #(#variants),* }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not derive Encode/Decode on uninhabited enums; model 'never' with a struct holding an uninhabited field instead.","Add a CI check that greps for `enum \\w+ \\{\\s*\\}` near ast_node derives."],"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"}