karatelabs/karate · error · TypeError

Constructor WeakSet requires 'new'

Error message

Constructor WeakSet requires 'new'

What it means

WeakSet is constructor-only: calling it without new is a TypeError per spec. Karate's JsWeakSetConstructor.call reads CallInfo.constructor and throws 'Constructor WeakSet requires new' when the call was not a construction.

Solutions

  1. Always use new WeakSet().
  2. Wrap for dual-style use: function mkWeakSet(){ return new WeakSet(); }.
  3. Grep scripts for bare `WeakSet(` calls and fix them.
  4. If you need a factory, return new WeakSet() from a named helper.

Example fix

// before
const ws = WeakSet();

// after
const ws = new WeakSet();
Defensive patterns

Strategy: validation

Try / catch

try { var ws = WeakSet(); } catch (e) { if (String(e).indexOf('requires') !== -1) ws = new WeakSet(); }

Prevention

When it happens

Trigger: Evaluating `const ws = WeakSet()` in Karate JS; `const S = WeakSet; S()`; reflection-driven or generated code that omits the new keyword.

Common situations: Refactoring that lost `new`; copying call-style from factory functions; dynamic constructor invocation via variable indirection.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/js/JsWeakSetConstructor.java:44

/**
 * Global {@code WeakSet} constructor — mirrors {@link JsSetConstructor}: no
 * {@code new} is a TypeError, and construction from an iterable invokes
 * {@code this.add(v)} through the prototype chain so a user-overridden
 * {@code WeakSet.prototype.add} is honored.
 */
class JsWeakSetConstructor extends JsFunction {

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

View on GitHub (pinned to a22eb90246)