swc-project/swc · error
attr_to_prop(JSXEmptyExpr)
Error message
attr_to_prop(JSXEmptyExpr)
What it means
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.
Source
Thrown at crates/swc_ecma_transforms_react/src/jsx/mod.rs:1123
let value = transform_jsx_attr_str(&s.value);
Lit::Str(Str {
span: s.span,
raw: None,
value: value.into(),
})
.into()
}
JSXAttrValue::JSXExprContainer(JSXExprContainer {
expr: JSXExpr::Expr(e),
..
}) => e,
JSXAttrValue::JSXElement(element) => Box::new(self.jsx_elem_to_expr(*element)),
JSXAttrValue::JSXFragment(fragment) => Box::new(self.jsx_frag_to_expr(fragment)),
JSXAttrValue::JSXExprContainer(JSXExprContainer {
span: _,
expr: JSXExpr::JSXEmptyExpr(_),
}) => unreachable!("attr_to_prop(JSXEmptyExpr)"),
#[cfg(swc_ast_unknown)]
_ => panic!("unable to access unknown nodes"),
})
.unwrap_or_else(|| {
Lit::Bool(Bool {
span: key.span(),
value: true,
})
.into()
});
Prop::KeyValue(KeyValueProp { key, value })
}
}
impl<C> Jsx<C>
where
C: Comments,
{View on GitHub (pinned to 5176682b65)
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.
Example fix
// before: attribute with empty expression container (invalid)
<div data-x={}>hello</div>
// after: boolean shorthand (data-x={true}) or a concrete value
<div data-x>hello</div>
<div data-x={value}>hello</div> Defensive patterns
Strategy: type-guard
Validate before calling
use swc_ecma_ast::{JSXAttr, JSXAttrValue, JSXExpr, JSXExprContainer};
fn attr_has_value(a: &JSXAttr) -> bool {
!matches!(&a.value, Some(JSXAttrValue::JSXExprContainer(JSXExprContainer {
expr: JSXExpr::JSXEmptyExpr(_), ..
})))
} Type guard
fn is_valid_attr_value(v: &JSXAttrValue) -> bool {
!matches!(v, JSXAttrValue::JSXExprContainer(c) if matches!(c.expr, JSXExpr::JSXEmptyExpr(_)))
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: JSX codegen tools emitting `attr={}` for empty attributes; ASTs round-tripped through estree/babel conversions; tests hand-building JSXAttr values.
Related errors
- failed to parse jsx option {}: '{}' is not an expression
- empty expression container
- Duplicate __source is found
- Duplicate __self is found
- invalid syntax
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/54f7f4b1a0b3be47.
Report an issue: GitHub.