{"record":{"id":"1e4c74b61d1e8cba","repo":"karatelabs/karate","slug":"cannot-set-on-node","errorCode":null,"errorMessage":"cannot set on: ${node}","messagePattern":"cannot set on: (.+?)","errorType":"exception","errorClass":"JsErrorException (typeError)","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/PropertyAccess.java","lineNumber":297,"sourceCode":"     */\n    static void set(Node node, CoreContext context, Object value, Node trackingNode) {\n                switch (node.type) {\n            case REF_EXPR -> {\n                int slot = node.slot;\n                Object[] frame;\n                if (slot >= 0 && (frame = context.frame) != null && frame[slot] != SlotTable.UNDECLARED) {\n                    context.updateSlot(slot, value, trackingNode);\n                } else {\n                    context.update(node.getText(), value, trackingNode);\n                }\n            }\n            case REF_DOT_EXPR, REF_BRACKET_EXPR -> {\n                AccessSite site = resolveWriteSite(node, context);\n                if (site == null || site == SHORT_CIRCUIT_SITE) return;\n                if (site.privateName != null) PrivateAccess.set(site.target, site.privateName, value, context);\n                else siteWrite(site, value, context, trackingNode);\n            }\n            default -> throw JsErrorException.typeError(\"cannot set on: \" + node);\n        }\n    }\n\n    //=== Assignment and compound operations ===\n\n    /**\n     * Simple assignment (`=`) in spec §13.15.2 evaluation order: the LHS\n     * Reference — base object and computed key — is evaluated BEFORE the RHS\n     * expression, and an abrupt completion at either step skips the write.\n     * Returns the assigned value (the value of the whole assignment\n     * expression).\n     */\n    static Object assign(Node node, CoreContext context, Node rhsNode, Node trackingNode) {\n                return switch (node.type) {\n            case REF_EXPR -> {\n                // An identifier Reference resolves without observable side\n                // effects; an unresolvable name only throws at PutValue time,\n                // which is after the RHS has been evaluated.","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/PropertyAccess.java#L279-L315","documentation":"`PropertyAccess.set` only knows how to write through dot/bracket reference nodes (resolving an AccessSite first). Any other node kind on the left of an assignment reaches the default branch and throws this TypeError naming the node, because the engine cannot form a writable reference from it.","triggerScenarios":"Assigning to an expression that is not a dot or bracket property reference, e.g. `f() = 1`, `(a, b) = 2`, or a literal on the LHS of `=` evaluated through the set path.","commonSituations":"Typos like `if (x = 5)` reversed (`5 = x`); template-generated code producing invalid assignment targets; destructuring attempted with plain `=` against a call result.","solutions":["Assign to a variable or a `obj.prop` / `obj[expr]` target instead of a call or literal.","Fix the operand order if a comparison was intended (`==`/`===`).","Use destructuring syntax `let {a, b} = ...` rather than assigning to a parenthesized list."],"exampleFix":"// before\ngetResult() = 5; // TypeError: cannot set on: FN_CALL...\n// after\nvar result = getResult();","handlingStrategy":"validation","validationCode":"// ensure assignment LHS is an identifier or property path\nconst lhs = code.split('=')[0].trim();\nif (!/^[A-Za-z_$][\\w$]*(\\.[\\w$]+|\\[[^\\]]+\\])*$/.test(lhs)) throw new Error('invalid assignment target: ' + lhs);","typeGuard":"function isWritableTarget(node) { return ['REF_DOT_EXPR','REF_BRACKET_EXPR','IDENT'].includes(node && node.type); }","tryCatchPattern":"try { engine.set(name, value); } catch (e) { if (String(e.message).startsWith('cannot set on:')) { /* normalize the LHS */ } else { throw e; } }","preventionTips":["Assign only to variables or obj.prop / obj[expr].","Avoid calls, literals, and parenthesized lists on the LHS of `=`.","Use destructuring declarations instead of assigning to expressions."],"tags":["javascript","assignment","type-error","ast"],"backgroundTag":"invalid-argument-value","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}