swc-project/swc · error

assign property in object literal is invalid

Error message

assign property in object literal is invalid

What it means

The es2015 computed-properties pass rewrites object-literal props into indexed assignments. Prop::Assign (`{ x = 1 }`) is a legacy strawman shorthand-with-default that standard object literals do not support; the standard parser does not produce it for valid ES, so reaching this arm means the AST contains a non-standard node (from custom codegen or an old-proposal transform) and the pass panics rather than guessing semantics.

Source

Thrown at crates/swc_ecma_compat_es2015/src/computed_props.rs:147

                                if self.c.loose {
                                    ident.clone().into()
                                } else {
                                    Lit::Str(Str {
                                        span: ident.span,
                                        raw: None,
                                        value: ident.sym.clone().into(),
                                    })
                                    .into()
                                },
                                false,
                            ),
                            ident.into(),
                        ),
                        Prop::KeyValue(KeyValueProp { key, value }) => {
                            (prop_name_to_expr(key, self.c.loose), *value)
                        }
                        Prop::Assign(..) => {
                            unreachable!("assign property in object literal is invalid")
                        }
                        prop @ Prop::Getter(GetterProp { .. })
                        | prop @ Prop::Setter(SetterProp { .. }) => {
                            self.used_define_enum_props = true;

                            // getter/setter property name
                            let gs_prop_name = match prop {
                                Prop::Getter(..) => Some("get"),
                                Prop::Setter(..) => Some("set"),
                                _ => None,
                            };
                            let (key, function) = match prop {
                                Prop::Getter(GetterProp { key, function, .. }) => (key, function),
                                Prop::Setter(SetterProp { key, function, .. }) => (key, function),
                                _ => unreachable!(),
                            };

                            // mutator[f]

View on GitHub (pinned to 5176682b65)

Solutions

  1. Do not emit Prop::Assign in object literals — write `{ x: value }` and apply defaults elsewhere
  2. If you build AST programmatically, convert Prop::Assign into Prop::KeyValue before running compat passes
  3. If plain parsed source reaches it, report to swc — the parser should have rejected the syntax

Example fix

// before
const opts = { retries = 3, timeout = 1000 };

// after
const opts = { retries: 3, timeout: 1000 };
Defensive patterns

Strategy: validation

Validate before calling

// Reject legacy `{ x = default }` object-literal syntax in inputs
let assign_prop = regex::Regex::new(r"\{\s*[A-Za-z_$][\w$]*\s*=(?!=)").unwrap();
if assign_prop.is_match(&js_source) {
    return Err("object literal shorthand-with-default is not valid ES".into());
}

Type guard

// Guard AST you build yourself before running compat passes
fn has_assign_prop(m: &swc_ecma_ast::Module) -> bool {
    struct V(bool);
    impl Visit for V {
        fn visit_prop(&mut self, p: &Prop) {
            if matches!(p, Prop::Assign(_)) { self.0 = true; }
            p.visit_children_with(self);
        }
    }
    let mut v = V(false);
    m.visit_with(&mut v);
    v.0
}

Try / catch

if let Err(p) = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| computed_props(&mut program))) {
    if panic_message(&p).contains("assign property") {
        // convert Prop::Assign nodes to Prop::KeyValue in your generator, then retry
    } else { std::panic::resume_unwind(p); }
}

Prevention

When it happens

Trigger: Passing AST containing Prop::Assign nodes — built programmatically, deserialized, or emitted by transforms mimicking the old object-default proposal — to swc_ecma_compat_es2015::computed_props.

Common situations: Downstream tools constructing object literals with `{x = default}` proposal syntax; hand-rolled AST builders; forks of older swc transforms that still model that proposal.

Related errors


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