karatelabs/karate · error · TypeError

Set.prototype.add is not callable

Error message

Set.prototype.add is not callable

What it means

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.

Solutions

  1. Do not delete or overwrite Set.prototype.add; restore it if patched.
  2. Check for global prototype-pollution code that assigns non-functions to built-in prototype members.
  3. Update to a version of the library/engine where the Set prototype is intact.

Example fix

// before
delete Set.prototype.add; // or Set.prototype.add = 'x'
// after
Set.prototype.add = function (v) { /* original impl */ return this; };
Defensive patterns

Strategy: validation

Validate before calling

if (typeof Set === 'undefined' || typeof Set.prototype.add !== 'function') throw new Error('Set prototype is broken');

Type guard

function setPrototypeIntact() { return typeof Set.prototype.add === 'function'; }

Try / catch

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)); }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/0a1c3c3161cce572. Report an issue: GitHub.

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/js/JsSetConstructor.java:56

    private void installIntrinsics() {
        defineOwn("prototype", JsSetPrototype.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 Set requires 'new'");
        }
        JsSet set = new JsSet();
        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("Set.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)