{"record":{"id":"0a1c3c3161cce572","repo":"karatelabs/karate","slug":"set-prototype-add-is-not-callable","errorCode":null,"errorMessage":"Set.prototype.add is not callable","messagePattern":"Set\\.prototype\\.add is not callable","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JsSetConstructor.java","lineNumber":56,"sourceCode":"\n    private void installIntrinsics() {\n        defineOwn(\"prototype\", JsSetPrototype.INSTANCE, PropertySlot.INTRINSIC);\n    }\n\n    @Override\n    public Object call(Context context, Object[] args) {\n        CallInfo callInfo = context.getCallInfo();\n        boolean isNew = callInfo != null && callInfo.constructor;\n        if (!isNew) {\n            throw JsErrorException.typeError(\"Constructor Set requires 'new'\");\n        }\n        JsSet set = new JsSet();\n        if (args.length == 0 || args[0] == null || args[0] == Terms.UNDEFINED) {\n            return set;\n        }\n        Object addFn = set.getMember(\"add\");\n        if (!(addFn instanceof JsCallable adder)) {\n            throw JsErrorException.typeError(\"Set.prototype.add is not callable\");\n        }\n        JsIterator iter = IterUtils.getIterator(args[0], context);\n        CoreContext cc = context instanceof CoreContext c ? c : null;\n        Object savedThis = cc != null ? cc.thisObject : null;\n        try {\n            while (iter.hasNext()) {\n                Object v = iter.next();\n                if (cc != null) cc.thisObject = set;\n                adder.call(context, new Object[]{v});\n                if (cc != null && cc.isError()) {\n                    return set;\n                }\n            }\n        } finally {\n            if (cc != null) cc.thisObject = savedThis;\n        }\n        return set;\n    }","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JsSetConstructor.java#L38-L74","documentation":"During new Set(iterable), the engine looked up `add` on the freshly created set to insert each element, but the member was not a callable function. This is an internal invariant violation — it means the Set prototype's `add` method is missing or was replaced by a non-function.","triggerScenarios":"new Set(iterable) when Set.prototype.add has been deleted, overwritten with a non-function, or when an incompatible patched prototype is installed before construction.","commonSituations":"Monkey-patching or polyfilling Set.prototype.add incorrectly; deleting methods from built-in prototypes in test setup; a custom class shadowing `add` via prototype reassignment.","solutions":["Do not delete or overwrite Set.prototype.add; restore it if patched.","Check for global prototype-pollution code that assigns non-functions to built-in prototype members.","Update to a version of the library/engine where the Set prototype is intact."],"exampleFix":"// before\ndelete Set.prototype.add; // or Set.prototype.add = 'x'\n// after\nSet.prototype.add = function (v) { /* original impl */ return this; };","handlingStrategy":"validation","validationCode":"if (typeof Set === 'undefined' || typeof Set.prototype.add !== 'function') throw new Error('Set prototype is broken');","typeGuard":"function setPrototypeIntact() { return typeof Set.prototype.add === 'function'; }","tryCatchPattern":"try { s = new Set(items); } catch (e) { if (String(e).includes('add is not callable')) s = new Set(); Array.from(items).forEach(v => s.add(v)); }","preventionTips":["Do not delete or overwrite built-in prototype methods.","Audit polyfills and monkey-patches in test setup.","Keep engine/library versions consistent."],"tags":["javascript","set","prototype"],"backgroundTag":"internal-invariant-violation","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"}