karatelabs/karate · error · TypeError
WeakSet.prototype.add is not callable
Error message
WeakSet.prototype.add is not callable
What it means
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.
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.
Example fix
// before delete WeakSet.prototype.add; const ws = new WeakSet([obj]); // TypeError // after const ws = new WeakSet(); ws.add(obj);
Defensive patterns
Strategy: validation
Validate before calling
if (typeof WeakSet.prototype.add !== 'function') throw new Error('WeakSet.prototype.add was clobbered'); Try / catch
try { var ws = new WeakSet(values); } catch (e) { var ws2 = new WeakSet(); values.forEach(v => ws2.add(v)); } Prevention
- Do not overwrite or delete WeakSet.prototype.add
- Restore saved originals after any patching
- Use explicit add() loops instead of iterable construction
When it happens
Trigger: 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.
Common situations: Monkey-patching WeakSet.prototype.add and getting it wrong; deleting prototype methods; proxy/reflection experiments in embedded JS that break member lookup.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Map.prototype.set is not callable
- WeakMap.prototype.set is not callable
- Invalid value used in weak set
- Constructor WeakSet requires 'new'
- Method WeakSet.prototype called on incompatible receiver
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/6a72e4b3403a8884.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsWeakSetConstructor.java:52
JsWeakSetConstructor() {
this.name = "WeakSet";
defineOwn("prototype", JsWeakSetPrototype.INSTANCE, PropertySlot.INTRINSIC);
}
@Override
public Object call(Context context, Object[] args) {
CallInfo callInfo = context.getCallInfo();
boolean isNew = callInfo != null && callInfo.constructor;
if (!isNew) {
throw JsErrorException.typeError("Constructor WeakSet requires 'new'");
}
JsWeakSet set = new JsWeakSet();
if (args.length == 0 || args[0] == null || args[0] == Terms.UNDEFINED) {
return set;
}
Object addFn = set.getMember("add");
if (!(addFn instanceof JsCallable adder)) {
throw JsErrorException.typeError("WeakSet.prototype.add is not callable");
}
JsIterator iter = IterUtils.getIterator(args[0], context);
CoreContext cc = context instanceof CoreContext c ? c : null;
Object savedThis = cc != null ? cc.thisObject : null;
try {
while (iter.hasNext()) {
Object v = iter.next();
if (cc != null) cc.thisObject = set;
adder.call(context, new Object[]{v});
if (cc != null && cc.isError()) {
return set;
}
}
} finally {
if (cc != null) cc.thisObject = savedThis;
}
return set;
}View on GitHub (pinned to a22eb90246)