{"record":{"id":"5da8283986daa68c","repo":"swc-project/swc","slug":"assign-property-in-object-literal-is-invalid","errorCode":null,"errorMessage":"assign property in object literal is invalid","messagePattern":"assign property in object literal is invalid","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/swc_ecma_compat_es2015/src/computed_props.rs","lineNumber":147,"sourceCode":"                                if self.c.loose {\n                                    ident.clone().into()\n                                } else {\n                                    Lit::Str(Str {\n                                        span: ident.span,\n                                        raw: None,\n                                        value: ident.sym.clone().into(),\n                                    })\n                                    .into()\n                                },\n                                false,\n                            ),\n                            ident.into(),\n                        ),\n                        Prop::KeyValue(KeyValueProp { key, value }) => {\n                            (prop_name_to_expr(key, self.c.loose), *value)\n                        }\n                        Prop::Assign(..) => {\n                            unreachable!(\"assign property in object literal is invalid\")\n                        }\n                        prop @ Prop::Getter(GetterProp { .. })\n                        | prop @ Prop::Setter(SetterProp { .. }) => {\n                            self.used_define_enum_props = true;\n\n                            // getter/setter property name\n                            let gs_prop_name = match prop {\n                                Prop::Getter(..) => Some(\"get\"),\n                                Prop::Setter(..) => Some(\"set\"),\n                                _ => None,\n                            };\n                            let (key, function) = match prop {\n                                Prop::Getter(GetterProp { key, function, .. }) => (key, function),\n                                Prop::Setter(SetterProp { key, function, .. }) => (key, function),\n                                _ => unreachable!(),\n                            };\n\n                            // mutator[f]","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_ecma_compat_es2015/src/computed_props.rs#L129-L165","documentation":"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.","triggerScenarios":"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.","commonSituations":"Downstream tools constructing object literals with `{x = default}` proposal syntax; hand-rolled AST builders; forks of older swc transforms that still model that proposal.","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"],"exampleFix":"// before\nconst opts = { retries = 3, timeout = 1000 };\n\n// after\nconst opts = { retries: 3, timeout: 1000 };","handlingStrategy":"validation","validationCode":"// Reject legacy `{ x = default }` object-literal syntax in inputs\nlet assign_prop = regex::Regex::new(r\"\\{\\s*[A-Za-z_$][\\w$]*\\s*=(?!=)\").unwrap();\nif assign_prop.is_match(&js_source) {\n    return Err(\"object literal shorthand-with-default is not valid ES\".into());\n}","typeGuard":"// Guard AST you build yourself before running compat passes\nfn has_assign_prop(m: &swc_ecma_ast::Module) -> bool {\n    struct V(bool);\n    impl Visit for V {\n        fn visit_prop(&mut self, p: &Prop) {\n            if matches!(p, Prop::Assign(_)) { self.0 = true; }\n            p.visit_children_with(self);\n        }\n    }\n    let mut v = V(false);\n    m.visit_with(&mut v);\n    v.0\n}","tryCatchPattern":"if let Err(p) = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| computed_props(&mut program))) {\n    if panic_message(&p).contains(\"assign property\") {\n        // convert Prop::Assign nodes to Prop::KeyValue in your generator, then retry\n    } else { std::panic::resume_unwind(p); }\n}","preventionTips":["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"],"tags":["swc","compat","es2015","object-literal","legacy-syntax"],"backgroundTag":"legacy-object-shorthand-syntax","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","contentChangedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}