{"record":{"id":"75e464953ec8654a","repo":"karatelabs/karate","slug":"duplicate-proto-in-an-object-literal","errorCode":null,"errorMessage":"duplicate __proto__ in an object literal","messagePattern":"duplicate __proto__ in an object literal","errorType":"exception","errorClass":"ParserException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/parser/JsParser.java","lineNumber":642,"sourceCode":"            return false;\n        }\n        // B.3.1 compares the StringValue, so escaped spellings\n        // (\"__proto__\") count — decode before comparing\n        return PROTO_KEY.equals(JsLexer.unescapeStringLiteral(text.substring(1, text.length() - 1)));\n    }\n\n    /** §13.2.5.1: at most one {@code __proto__: value} proto-setter per ObjectLiteral.\n     *  Duplicates are legal in a destructuring pattern (the cover grammar drops the\n     *  rule), so the caller gates on {@code !inPattern}. */\n    private static void checkNoDuplicateProtoSetter(Node litObject) {\n        boolean seen = false;\n        for (int i = 0, n = litObject.size(); i < n; i++) {\n            Node child = litObject.get(i);\n            if (child.isToken() || child.type != NodeType.OBJECT_ELEM || !isProtoSetter(child)) {\n                continue;\n            }\n            if (seen) {\n                throw new ParserException(\"duplicate __proto__ in an object literal\");\n            }\n            seen = true;\n        }\n    }\n\n    // Descent state for checkStaticBlockBody.\n    private static final int SB_FN = 1;       // inside a nested function — its own return / break target\n    private static final int SB_LOOP = 2;     // inside an iteration statement of the block's own\n    private static final int SB_SWITCH = 4;   // inside a switch statement of the block's own\n    private static final int SB_AWAIT_OK = 8; // inside a nested function's body — `await` is a name again\n\n    /**\n     * §15.7.1 early errors a class static initialization block carries. Every rule\n     * stops at the block boundary, so this descends that block's subtree only — a\n     * per-node helper of {@link #earlyErrors}, not a second traversal of the tree.\n     * <ul>\n     *   <li>{@code return} has no target: the body is not a function body.</li>\n     *   <li>{@code break} / {@code continue} may not reach out of the block. The","sourceCodeStart":624,"sourceCodeEnd":660,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/parser/JsParser.java#L624-L660","documentation":"An object literal may contain at most one `__proto__: value` setter; a duplicate is an early error. The Karate JS parser detects multiple `__proto__` property definitions in one object literal and throws. Note this only applies to the `{ __proto__: v }` setter form, not computed keys or `'__proto__'` string keys.","triggerScenarios":"Parsing `{ __proto__: a, __proto__: b }` or a literal where a spread/merge accidentally introduced a second `__proto__` key, detected by checkNoDuplicateProtoSetter.","commonSituations":"Merging two object literals by hand; code generation emitting a base `__proto__` plus a user-supplied one; copying properties including `__proto__` into a literal.","solutions":["Keep only one `__proto__:` entry in the literal.","Set the prototype after construction: `Object.setPrototypeOf(obj, proto)`.","Use `Object.create(proto)` when the prototype is the point of the object.","If merging, filter out duplicate `__proto__` keys before building the literal."],"exampleFix":"// before\nconst o = { __proto__: baseA, __proto__: baseB };\n// after\nconst o = { __proto__: baseB }; // or Object.setPrototypeOf(Object.create(null), baseB)","handlingStrategy":"validation","validationCode":"// detect duplicate __proto__ setter in an object literal string\nfunction singleProto(src) { return (src.match(/\\b__proto__\\s*:/g) || []).length <= 1; }","typeGuard":null,"tryCatchPattern":"try { karate.eval(objSrc); } catch (e) { if (String(e).includes('duplicate __proto__')) { /* keep one or use setPrototypeOf */ } }","preventionTips":["Prefer `Object.create(proto)` or `Object.setPrototypeOf` over `__proto__:` in literals.","Filter `__proto__` keys when merging/generated object literals.","Reserve `__proto__:` for one deliberate prototype assignment per literal."],"tags":["javascript","parser","syntax-error","object-literal","proto"],"backgroundTag":"javascript-syntax-error","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"}