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

  1. Do not overwrite or delete WeakMap.prototype.set in your Karate JS scripts.
  2. Restore the original: WeakMap.prototype.set = originalSet (capture it before patching).
  3. Construct with explicit set calls instead of an iterable argument to bypass the adder path.
  4. 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

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


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)