karatelabs/karate · error · TypeError

Constructor Set requires 'new'

Error message

Constructor Set requires 'new'

What it means

The Set constructor was invoked as a plain function without `new`. The engine implements Set as a constructor-only callable, so a missing `new` is a TypeError rather than silently returning a set (spec-compliant engines may allow it, this one deliberately does not).

Solutions

  1. Add `new`: new Set(iterable).
  2. Wrap in a factory if you need call-style construction: const makeSet = (it) => new Set(it).
  3. Do not pass Set directly as a callback; use an arrow wrapper: arr.map(x => new Set(x)).

Example fix

// before
const s = Set([1, 2, 3]);
// after
const s = new Set([1, 2, 3]);
Defensive patterns

Strategy: type-guard

Type guard

function isSet(v) { return v instanceof Set; }

Try / catch

try { return Set(items); } catch (e) { if (String(e).includes("requires 'new'")) return new Set(items); throw e; }

Prevention

When it happens

Trigger: Calling Set([1,2,3]) directly instead of new Set([1,2,3]); destructuring Set from a namespace and calling it; using Set as a callback, e.g. arr.map(Set).

Common situations: Refactors that dropped `new`; code written for engines/DSLs where Set is callable without new; minified or transpiled output that lost the constructor call.

Related errors


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

Appendix: source

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

 * {@code Set.prototype.add} is honored.
 */
class JsSetConstructor extends JsFunction {
    JsSetConstructor() {
        this.name = "Set";
        // length=0 — Set() takes optional iterable; spec arity is 0.
        installIntrinsics();
    }

    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()) {

View on GitHub (pinned to a22eb90246)