karatelabs/karate · error · TypeError
WeakMap.prototype.set is not callable
Error message
WeakMap.prototype.set is not callable
What it means
When constructing a WeakMap from an iterable of entries, the constructor fetches the map's own 'set' method to use as the adder. The spec guarantees set is callable, but if getMember("set") does not return a JsCallable (e.g. the prototype's set member was overwritten or is missing in this engine state), Karate throws this TypeError instead of proceeding.
Solutions
- Do not overwrite or delete WeakMap.prototype.set in your Karate JS scripts.
- Restore the original: WeakMap.prototype.set = originalSet (capture it before patching).
- Construct with explicit set calls instead of an iterable argument to bypass the adder path.
- Audit any reflection/proxy code that could shadow the 'set' member.
Example fix
// before WeakMap.prototype.set = 'oops'; const wm = new WeakMap([[k, v]]); // TypeError // after const wm = new WeakMap(); wm.set(k, v);
Defensive patterns
Strategy: validation
Validate before calling
if (typeof WeakMap.prototype.set !== 'function') throw new Error('WeakMap.prototype.set was clobbered'); Try / catch
try { var wm = new WeakMap(entries); } catch (e) { var wm2 = new WeakMap(); entries.forEach(en => wm2.set(en[0], en[1])); } Prevention
- Do not monkey-patch or delete WeakMap.prototype members
- Save originals before any patching and restore them
- Prefer explicit set() calls over iterable construction in embedded engines
When it happens
Trigger: new WeakMap(iterable) where the JsWeakMap instance's 'set' member fails to resolve to a JsCallable — typically only if prototype methods have been tampered with or shadowed, since normal scripts can't usually cause it.
Common situations: Monkey-patching or deleting WeakMap.prototype.set earlier in the same JS evaluation; assigning a non-function to map.set before/while constructing from an iterable; exotic host-object interactions in embedded engines.
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
- Invalid value used as weak map key
- Constructor WeakMap requires 'new'
- Iterator value is not an entry object
- Method WeakMap.prototype called on incompatible receiver
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/84285bd77a6ee099.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsWeakMapConstructor.java:54
JsWeakMapConstructor() {
this.name = "WeakMap";
defineOwn("prototype", JsWeakMapPrototype.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 WeakMap requires 'new'");
}
JsWeakMap map = new JsWeakMap();
if (args.length == 0 || args[0] == null || args[0] == Terms.UNDEFINED) {
return map;
}
Object setFn = map.getMember("set");
if (!(setFn instanceof JsCallable adder)) {
throw JsErrorException.typeError("WeakMap.prototype.set 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 entry = iter.next();
if (!(entry instanceof List) && !(entry instanceof ObjectLike)) {
throw JsErrorException.typeError("Iterator value " + entry + " is not an entry object");
}
Object k;
Object v;
if (entry instanceof List<?> list) {
k = list.isEmpty() ? Terms.UNDEFINED : list.get(0);
v = list.size() < 2 ? Terms.UNDEFINED : list.get(1);
} else {
ObjectLike ol = (ObjectLike) entry;
k = ol.getMember("0");View on GitHub (pinned to a22eb90246)