{"record":{"id":"5ce9a8f4524ffbf1","repo":"karatelabs/karate","slug":"invalid-shorthand-initializer-only-allowed-in-destructuring","errorCode":null,"errorMessage":"invalid shorthand initializer: only allowed in destructuring pattern","messagePattern":"invalid shorthand initializer: only allowed in destructuring pattern","errorType":"exception","errorClass":"ParserException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/parser/JsParser.java","lineNumber":214,"sourceCode":"     * always null unless the file used a label) — and recomputes each for the children. The\n     * per-node check bodies live in dedicated helpers so this stays the one place\n     * the tree is walked; a new early-error rule plugs in as another helper call,\n     * not another traversal.\n     * <p>\n     * Per-node check order mirrors the former pass order\n     * (assignment-target/decl-position → CoverInitializedName → strict-mode) so a\n     * node that could trip more than one rule reports the same message as before.\n     */\n    private void earlyErrors(Node node, boolean strict, boolean inPattern, PrivateScope privates, Label labels) {\n        if (node == null) {\n            return;\n        }\n        // Mode-independent: assignment-target validity, optional-chain restrictions,\n        // declaration-in-statement-position.\n        earlyErrorNodeChecks(node);\n        // CoverInitializedName / rest-element rules, gated on pattern context.\n        if (node.type == NodeType.OBJECT_ELEM && hasCoverInitForm(node) && !inPattern) {\n            throw new ParserException(\"invalid shorthand initializer: only allowed in destructuring pattern\");\n        }\n        if (inPattern && node.type == NodeType.LIT_ARRAY) {\n            validateRestElementRules(node);\n        }\n        // §15.7.1 static-block family — scans only the block's own subtree.\n        if (node.type == NodeType.CLASS_STATIC_BLOCK) {\n            checkStaticBlockBody(node, 0);\n        }\n        // At most one B.3.1 proto-setter per ObjectLiteral; not a rule for patterns.\n        if (sawProtoKey && !inPattern && node.type == NodeType.LIT_OBJECT) {\n            checkNoDuplicateProtoSetter(node);\n        }\n        // Private-name family; returns the private scope to propagate to children.\n        PrivateScope childPrivates = sawPrivateName ? privateNodeChecks(node, privates) : privates;\n        // Strict-mode family; returns the strictness to propagate to children.\n        boolean childStrict = strictNodeChecks(node, strict);\n        // Label family; returns the label chain to propagate to children.\n        Label childLabels = sawLabel ? labelNodeChecks(node, labels) : null;","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/parser/JsParser.java#L196-L232","documentation":"Karate's JS parser implements ES2015+ early errors: a shorthand object property with an initializer ({a = 1}) is only legal inside a destructuring pattern. When the parser finds such a form in a normal object literal (assignment/expression context), it throws this ParserException immediately after building the node. This mirrors V8's \"Shorthand property assignments are valid only within destructuring patterns\".","triggerScenarios":"Writing an object literal like `({ a = 1 })` or `({ a = 1, b })` where `{a = 1}` is parsed as an OBJECT_ELEM with a cover-initialization form while the parser's `inPattern` flag is false — i.e. the code appears in a plain expression, argument, or return value rather than the target of a destructuring assignment or declaration.","commonSituations":"Typos when intending destructuring (writing `const {a = 1}` as `const a = {b = 2}`), hand-written Karate JS embedded in feature files where `{}` braces conflict with the surrounding syntax, or porting code that relied on sloppy non-standard parser behavior.","solutions":["Wrap the code in a destructuring context: `const { a = 1 } = obj;` instead of using `{ a = 1 }` as an expression","If you meant a default property value, use a spread or explicit assignment: `{ a: obj.a !== undefined ? obj.a : 1 }` or `{ ...{ a: 1 }, ...obj }`","Check for brace mismatches (e.g. in Karate feature-file embedded JS) that make a destructuring pattern look like an object literal"],"exampleFix":"// before\nconst a = { b = 1 };\n// after\nconst { b = 1 } = obj;","handlingStrategy":"validation","validationCode":"// Only use `=` defaults inside destructuring patterns:\nconst ok = /const\\s*\\{|let\\s*\\{|var\\s*\\{|=\\s*\\[|^\\s*\\(\\s*\\{/.test(src); // heuristic — ensure {a = 1} appears only after const/let/var or a call target","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Reserve `=` defaults for destructuring declarations only","Lint embedded feature-file JS for `{ ident = ` outside const/let/var","Double-check brace pairing when JS is embedded in Karate feature files"],"tags":["javascript","parser","syntax","destructuring"],"backgroundTag":"invalid-destructuring-pattern","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}