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

  1. Fix the JSX producer: emit no attribute at all, or a real value (`attr={null}` / `attr={true}` / omit the value for boolean-true semantics).
  2. If consuming foreign ASTs, validate JSXAttrValue before running the React transform (see type guard).
  3. 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

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


AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17). Data as JSON: /api/errors/54f7f4b1a0b3be47. Report an issue: GitHub.