{"record":{"id":"5428b8f1dca261c9","repo":"karatelabs/karate","slug":"setter-must-be-a-function","errorCode":null,"errorMessage":"Setter must be a function","messagePattern":"Setter must be a function","errorType":"exception","errorClass":"JsErrorException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JsObjectConstructor.java","lineNumber":639,"sourceCode":"        // {@code defineProperty/15.2.3.6-3-{8,13}}). Only literal undefined\n        // is the spec-permitted \"absent\" sentinel.\n        JsCallable newGetter = null;\n        JsCallable newSetter = null;\n        if (isAccessor) {\n            if (hasGet) {\n                Object g = descRead(descObj, descMap, \"get\", cc);\n                if (g != Terms.UNDEFINED) {\n                    if (!(g instanceof JsCallable c)) {\n                        throw JsErrorException.typeError(\"Getter must be a function\");\n                    }\n                    newGetter = c;\n                }\n            }\n            if (hasSet) {\n                Object s = descRead(descObj, descMap, \"set\", cc);\n                if (s != Terms.UNDEFINED) {\n                    if (!(s instanceof JsCallable c)) {\n                        throw JsErrorException.typeError(\"Setter must be a function\");\n                    }\n                    newSetter = c;\n                }\n            }\n        }\n\n        // A symbol key addresses the symbol store — the validation below is\n        // indexed by `prop`, which a symbol key does not have.\n        if (symKey != null) {\n            if (!(target instanceof JsObject jo)) {\n                return target;\n            }\n            PropertySlot prior = jo.ownSymbolSlot(symKey);\n            if (prior == null && !jo.isExtensible()) {\n                throw JsErrorException.typeError(\n                        \"Cannot define property \" + symKey + \", object is not extensible\");\n            }\n            // new keys default to all-false per ValidateAndApplyPropertyDescriptor","sourceCodeStart":621,"sourceCodeEnd":657,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JsObjectConstructor.java#L621-L657","documentation":"Symmetric to the getter check: a 'set' field present (and not undefined) in a property descriptor must be a callable function. Passing null, a value, or any non-callable throws this TypeError per ToPropertyDescriptor.","triggerScenarios":"Object.defineProperty(obj, 'k', { set: true }) or { set: null } or { set: someNonFunction }.","commonSituations":"Passing a stored callback variable that is actually undefined-transformed-to-null; mixing up value and set fields; descriptors round-tripped through JSON losing function identity.","solutions":["Pass a real function to set: (obj, 'k', { set(v) { this._k = v; } })","Omit the set field for read-only accessor or data descriptors","Use undefined (not null) if you need the key present but inert","Guard with typeof desc.set === 'function' before defining"],"exampleFix":"// before\nObject.defineProperty(o, 'x', { set: 42 });\n// after\nObject.defineProperty(o, 'x', { set(v) { this._x = v; } });","handlingStrategy":"type-guard","validationCode":"if (desc.set !== undefined && typeof desc.set !== 'function') throw new TypeError('set must be a function or undefined');","typeGuard":"function hasValidSetter(desc) { return !('set' in desc) || desc.set === undefined || typeof desc.set === 'function'; }","tryCatchPattern":"try { Object.defineProperty(o, k, desc); } catch (e) { if (String(e.message).includes('Setter must be a function')) console.error('descriptor.set =', desc.set); else throw e; }","preventionTips":["Validate accessor pairs together: both get and set must be functions or undefined","Avoid storing setter callbacks in variables that may hold values/undefined","Prefer object-literal getters/setters (get x() {...}) over manual descriptors"],"tags":["javascript","descriptor","accessor","typeerror"],"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-16T19:17:19.609Z"}