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
- Do not emit Prop::Assign in object literals — write `{ x: value }` and apply defaults elsewhere
- If you build AST programmatically, convert Prop::Assign into Prop::KeyValue before running compat passes
- 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
- Never emit `{ x = 1 }` in object literals; use `{ x: 1 }`
- Validate programmatically built AST with a Prop::Assign visitor before transforms
- Keep object-literal codegen in your tooling aligned with standard ES syntax
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
- using declaration must be removed by previous pass
- rest pattern should handled by array pattern handler: {:?}
- Object rest pattern should be removed by es2018::object_rest
- illegal conversion: Cannot convert {:?} to ObjectKey - babel
- illegal conversion: Cannot convert {:?} to ObjectMember
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/5da8283986daa68c.
Report an issue: GitHub.