{"record":{"id":"9914c4f291cc07d6","repo":"swc-project/swc","slug":"multiple-constructor","errorCode":null,"errorMessage":"multiple constructor?","messagePattern":"multiple constructor\\?","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/swc_ecma_transforms_proposal/src/decorators/mod.rs","lineNumber":439,"sourceCode":"                                    }\n                                    .into(),\n                                ),\n                            },\n                        )))))\n                        .collect(),\n                    }\n                    .as_arg(),\n                )\n            }};\n        }\n\n        let descriptors = class\n            .body\n            .into_iter()\n            .filter_map(|member| {\n                //\n                match member {\n                    ClassMember::Constructor(_) => unreachable!(\"multiple constructor?\"),\n                    ClassMember::Empty(_) | ClassMember::TsIndexSignature(_) => None,\n                    ClassMember::Method(method) => {\n                        let fn_name = match method.key {\n                            PropName::Ident(ref i) => Some(i.clone()),\n                            PropName::Str(ref s) => s\n                                .value\n                                .as_str()\n                                .map(|sym| IdentName::new(Atom::from(sym), s.span)),\n                            _ => None,\n                        };\n                        let key_prop_value = Box::new(prop_name_to_expr_value(method.key.clone()));\n\n                        fold_method!(method, fn_name, key_prop_value)\n                    }\n                    ClassMember::PrivateMethod(method) => {\n                        let fn_name = Ident::new_no_ctxt(\n                            format!(\"_{}\", method.key.name).into(),\n                            method.key.span,","sourceCodeStart":421,"sourceCodeEnd":457,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_ecma_transforms_proposal/src/decorators/mod.rs#L421-L457","documentation":"The decorator transform (swc_ecma_transforms_proposal::decorators) builds property descriptors from a class body; by the time this filter_map runs, the constructor has already been extracted and removed from the member list, so encountering another ClassMember::Constructor is treated as `multiple constructor?`. The parser itself rejects duplicate constructors, so this unreachable! signals a mutated/hand-built class AST rather than parsed source.","triggerScenarios":"Programmatically constructed or transform-modified Class AST where two ClassMember::Constructor nodes exist (custom decorators, class-mutation passes, AST round-trips through FFI/serde that duplicate members), compiled with the 2022-era decorators option.","commonSituations":"Decorator plugin ecosystems that rewrite class bodies before the decorator pass; codemods synthesizing classes; swc AST serialized by one version and deserialized by another re-adding members.","solutions":["Validate the class body before the decorator pass: exactly zero-or-one Constructor member.","Fix the upstream pass that injects or duplicates constructor members into the class body.","If the class comes from parsed source, report an swc bug with the repro (the parser should have rejected it)."],"exampleFix":"// before: synthesized AST accidentally carries two constructors\nclass.body.push(ClassMember::Constructor(second_ctor));\n\n// after: mutate in place, keep a single constructor\nif let Some(ClassMember::Constructor(existing)) = class.body.iter_mut().find(|m| matches!(m, ClassMember::Constructor(_))) {\n    *existing = new_ctor;\n}","handlingStrategy":"validation","validationCode":"use swc_ecma_ast::{ClassMember, Class};\nfn single_constructor(c: &Class) -> bool {\n    c.body.iter().filter(|m| matches!(m, ClassMember::Constructor(_))).count() <= 1\n}\n// assert!(single_constructor(&class)) before the decorators pass","typeGuard":"fn has_valid_ctor_count(c: &Class) -> bool { c.body.iter().filter(|m| matches!(m, ClassMember::Constructor(_))).count() <= 1 }","tryCatchPattern":null,"preventionTips":["Never inject ClassMember::Constructor into bodies mid-transform; mutate the existing one.","Validate class bodies after foreign AST conversion and before decorator passes.","Serialize/deserialize ASTs with the same swc version on both ends."],"tags":["swc","decorators","class-ast","constructor","ast-invariant","panic"],"backgroundTag":"compiler-internal-panic","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"}