{"record":{"id":"54f7f4b1a0b3be47","repo":"swc-project/swc","slug":"attr-to-prop-jsxemptyexpr","errorCode":null,"errorMessage":"attr_to_prop(JSXEmptyExpr)","messagePattern":"attr_to_prop\\(JSXEmptyExpr\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/swc_ecma_transforms_react/src/jsx/mod.rs","lineNumber":1123,"sourceCode":"                    let value = transform_jsx_attr_str(&s.value);\n\n                    Lit::Str(Str {\n                        span: s.span,\n                        raw: None,\n                        value: value.into(),\n                    })\n                    .into()\n                }\n                JSXAttrValue::JSXExprContainer(JSXExprContainer {\n                    expr: JSXExpr::Expr(e),\n                    ..\n                }) => e,\n                JSXAttrValue::JSXElement(element) => Box::new(self.jsx_elem_to_expr(*element)),\n                JSXAttrValue::JSXFragment(fragment) => Box::new(self.jsx_frag_to_expr(fragment)),\n                JSXAttrValue::JSXExprContainer(JSXExprContainer {\n                    span: _,\n                    expr: JSXExpr::JSXEmptyExpr(_),\n                }) => unreachable!(\"attr_to_prop(JSXEmptyExpr)\"),\n                #[cfg(swc_ast_unknown)]\n                _ => panic!(\"unable to access unknown nodes\"),\n            })\n            .unwrap_or_else(|| {\n                Lit::Bool(Bool {\n                    span: key.span(),\n                    value: true,\n                })\n                .into()\n            });\n        Prop::KeyValue(KeyValueProp { key, value })\n    }\n}\n\nimpl<C> Jsx<C>\nwhere\n    C: Comments,\n{","sourceCodeStart":1105,"sourceCodeEnd":1141,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_ecma_transforms_react/src/jsx/mod.rs#L1105-L1141","documentation":"attr_to_prop in the React JSX transform converts a JSXAttrValue into a plain object-literal property value. A JSXExprContainer holding JSXEmptyExpr (i.e. an attribute written as `attr={}`) carries no expression to convert, so this unreachable! fires. Empty expression containers are legal only as JSX children (`{/* comment */}`), never as attribute values — the parser rejects them, so this comes from programmatic ASTs.","triggerScenarios":"Passing a JSX attribute whose value is an empty expression container to the React transform — produced by AST generators/templating tools or lenient parsers, since swc's parser itself errors on `attr={}` in source.","commonSituations":"JSX codegen tools emitting `attr={}` for empty attributes; ASTs round-tripped through estree/babel conversions; tests hand-building JSXAttr values.","solutions":["Fix the JSX producer: emit no attribute at all, or a real value (`attr={null}` / `attr={true}` / omit the value for boolean-true semantics).","If consuming foreign ASTs, validate JSXAttrValue before running the React transform (see type guard).","Report to the tool that generated the empty-expression attribute."],"exampleFix":"// before: attribute with empty expression container (invalid)\n<div data-x={}>hello</div>\n\n// after: boolean shorthand (data-x={true}) or a concrete value\n<div data-x>hello</div>\n<div data-x={value}>hello</div>","handlingStrategy":"type-guard","validationCode":"use swc_ecma_ast::{JSXAttr, JSXAttrValue, JSXExpr, JSXExprContainer};\nfn attr_has_value(a: &JSXAttr) -> bool {\n    !matches!(&a.value, Some(JSXAttrValue::JSXExprContainer(JSXExprContainer {\n        expr: JSXExpr::JSXEmptyExpr(_), ..\n    })))\n}","typeGuard":"fn is_valid_attr_value(v: &JSXAttrValue) -> bool {\n    !matches!(v, JSXAttrValue::JSXExprContainer(c) if matches!(c.expr, JSXExpr::JSXEmptyExpr(_)))\n}","tryCatchPattern":null,"preventionTips":["Codegen: omit the attribute instead of emitting `attr={}`.","Validate foreign/estree-converted JSX before swc React transforms.","Empty expression containers are legal only as JSX children (comments), never attribute values."],"tags":["swc","react","jsx","jsx-attributes","empty-expression","invalid-ast","panic"],"backgroundTag":"invalid-jsx-ast","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}