{"record":{"id":"6a72e4b3403a8884","repo":"karatelabs/karate","slug":"weakset-prototype-add-is-not-callable","errorCode":null,"errorMessage":"WeakSet.prototype.add is not callable","messagePattern":"WeakSet\\.prototype\\.add is not callable","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JsWeakSetConstructor.java","lineNumber":52,"sourceCode":"    JsWeakSetConstructor() {\n        this.name = \"WeakSet\";\n        defineOwn(\"prototype\", JsWeakSetPrototype.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 WeakSet requires 'new'\");\n        }\n        JsWeakSet set = new JsWeakSet();\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(\"WeakSet.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":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JsWeakSetConstructor.java#L34-L70","documentation":"When building a WeakSet from an iterable, the constructor resolves the set's 'add' method to use as the adder. If getMember(\"add\") does not yield a JsCallable, Karate throws this TypeError rather than continuing, mirroring the spec's internal Adder creation failure.","triggerScenarios":"new WeakSet(iterable) where the instance's 'add' member is not a JsCallable — e.g. WeakSet.prototype.add was overwritten with a non-function, deleted, or shadowed earlier in the script.","commonSituations":"Monkey-patching WeakSet.prototype.add and getting it wrong; deleting prototype methods; proxy/reflection experiments in embedded JS that break member lookup.","solutions":["Leave WeakSet.prototype.add intact; undo any overwrites or deletions.","Restore from a saved reference: WeakSet.prototype.add = originalAdd.","Construct empty and call add() explicitly instead of passing an iterable.","Remove any code assigning non-function values to WeakSet.prototype members."],"exampleFix":"// before\ndelete WeakSet.prototype.add;\nconst ws = new WeakSet([obj]); // TypeError\n\n// after\nconst ws = new WeakSet();\nws.add(obj);","handlingStrategy":"validation","validationCode":"if (typeof WeakSet.prototype.add !== 'function') throw new Error('WeakSet.prototype.add was clobbered');","typeGuard":null,"tryCatchPattern":"try { var ws = new WeakSet(values); } catch (e) { var ws2 = new WeakSet(); values.forEach(v => ws2.add(v)); }","preventionTips":["Do not overwrite or delete WeakSet.prototype.add","Restore saved originals after any patching","Use explicit add() loops instead of iterable construction"],"tags":["javascript","weakset","prototype","typeerror"],"backgroundTag":"unsupported-operation","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"}