{"record":{"id":"4124d1ad31fdd6d0","repo":"swc-project/swc","slug":"illegal-conversion-cannot-convert-to-exprout-4124d1","errorCode":null,"errorMessage":"illegal conversion: Cannot convert {:?} to ExprOutput - babel has no equivalent","messagePattern":"illegal conversion: Cannot convert (.+?) to ExprOutput - babel has no equivalent","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/swc_estree_compat/src/babelify/expr.rs","lineNumber":146,"sourceCode":"            }\n            Expr::JSXElement(e) => {\n                ExprOutput::Expr(Box::alloc().init(Expression::JSXElement(e.babelify(ctx))))\n            }\n            Expr::JSXFragment(f) => {\n                ExprOutput::Expr(Box::alloc().init(Expression::JSXFragment(f.babelify(ctx))))\n            }\n            Expr::TsTypeAssertion(a) => {\n                ExprOutput::Expr(Box::alloc().init(Expression::TSTypeAssertion(a.babelify(ctx))))\n            }\n            Expr::TsNonNull(n) => {\n                ExprOutput::Expr(Box::alloc().init(Expression::TSNonNull(n.babelify(ctx))))\n            }\n            Expr::TsAs(a) => ExprOutput::Expr(Box::alloc().init(Expression::TSAs(a.babelify(ctx)))),\n            Expr::TsInstantiation(..) => unimplemented!(\"Babel doesn't support this right now.\"),\n            Expr::PrivateName(p) => ExprOutput::Private(p.babelify(ctx)),\n\n            // TODO(dwoznicki): how does babel handle these?\n            Expr::JSXMember(_) => panic!(\n                \"illegal conversion: Cannot convert {:?} to ExprOutput - babel has no equivalent\",\n                &self\n            ),\n            Expr::JSXNamespacedName(_) => panic!(\n                \"illegal conversion: Cannot convert {:?} to ExprOutput - babel has no equivalent\",\n                &self\n            ),\n            Expr::JSXEmpty(_) => panic!(\n                \"illegal conversion: Cannot convert {:?} to ExprOutput - babel has no equivalent\",\n                &self\n            ),\n            Expr::TsConstAssertion(_) => panic!(\n                \"illegal conversion: Cannot convert {:?} to ExprOutput - babel has no equivalent\",\n                &self\n            ),\n            Expr::TsSatisfies(_) => panic!(\n                \"illegal conversion: Cannot convert {:?} to ExprOutput - babel has no equivalent\",\n                &self","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_estree_compat/src/babelify/expr.rs#L128-L164","documentation":"Expr::JSXMember — the `Foo.Bar` in an element name like `<Foo.Bar />` — has no standalone Babel Expression equivalent (Babel's JSXMemberExpression is only legal inside JSX names), so the generic expression conversion panics at expr.rs:146. Normally JSXMember lives inside JSXElementName and is handled by the JSX element babelify path; hitting this arm means a JSXMember node was lifted into a plain expression slot.","triggerScenarios":"Babelifying an AST where a JSXMember appears as a general Expr — e.g. a plugin/codemod extracted an element name into an expression container or argument, or an AST fixture built with JSXMember in the wrong slot.","commonSituations":"swc plugins that rewrite JSX element names (e.g. renaming library prefixes); AST round-tripping tools; hand-written fixtures.","solutions":["Keep member element names inside JSXElement; let the JSX babelify path convert them.","Lower JSX first with the react transform so babelify never sees JSXMember.","If a name must be an expression, rewrite it to a plain Expr::Member (Ident.member) before babelify."],"exampleFix":"// before: lifted into an expression slot\nExpr::JSXMember(jsx_member_foo_bar)\n\n// after: plain member expression\nmember_expr(ident!(\"Foo\"), ident_name!(\"Bar\"))","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"fn has_jsxmember_in_expr(program: &Program) -> bool {\n    struct Scan(bool);\n    impl Visit for Scan {\n        fn visit_expr(&mut self, e: &Expr) {\n            if matches!(e, Expr::JSXMember(_)) { self.0 = true; }\n            e.visit_children_with(self);\n        }\n        fn visit_jsx_element(&mut self, _: &JSXElement) {}\n    }\n    let mut s = Scan(false);\n    program.visit_with(&mut s);\n    s.0\n}","tryCatchPattern":null,"preventionTips":["Lower JSX before estree conversion; JSXMember only converts inside the JSX element path.","When extracting element names in plugins, emit plain Expr::Member, not Expr::JSXMember.","Cover member-named elements (`<Foo.Bar/>`) in your conversion test fixtures."],"tags":["swc","estree","babelify","jsx","panic"],"backgroundTag":"ast-conversion-unsupported-node","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}