karatelabs/karate · error · JsErrorException

'super' keyword is only valid inside a class

Error message

'super' keyword is only valid inside a class

What it means

Thrown as a syntax error when `super(...)` is evaluated outside any active class function. `evalSuperCall` requires context.activeFunction (a JsFunctionNode from a class); if there is no active function, `super()` cannot have a parent constructor to run.

Solutions

  1. Ensure `super(...)` only appears in the constructor of a class with an `extends` clause.
  2. Remove `super()` from extracted/refactored code that is no longer inside a derived class.
  3. Replace `super(...)` calls in plain functions with an explicit `ParentClass.call(this, ...)`-style construction.

Example fix

// before
function makeChild() { super(1); }
// after
class Child extends Parent {
  constructor() { super(1); }
}
Defensive patterns

Strategy: validation

Try / catch

try { runSnippet(); } catch (e) { if (String(e).includes("'super' keyword")) { /* snippet needs class context */ } }

Prevention

When it happens

Trigger: Calling `super(...)` in a top-level script, inside a plain (non-class) function, inside an arrow function at script top level, or in a feature-file JS block not nested in a derived class constructor.

Common situations: Copying a derived-class constructor body out of its class wrapper into utility code; calling a class method containing `super()` as a standalone function.

Related errors


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

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/js/Interpreter.java:1344

            // with them, so a callee ran on the strength of an argument expression that had
            // already failed. The throw did surface afterwards, which is what made this invisible:
            // the exception was right and the side effects along the way were not.
            if (context.isError()) {
                break;
            }
        }
        if (spill != null) {
            return spill.toArray();
        }
        return n == args.length ? args : java.util.Arrays.copyOf(args, n);
    }

    // `super(...)` in a derived constructor — runs the parent constructor against
    // the instance currently under construction (context.thisObject).
    private static Object evalSuperCall(Node fnArgsNode, CoreContext context) {
        JsFunctionNode active = context.activeFunction;
        if (active == null) {
            throw JsErrorException.syntaxError("'super' keyword is only valid inside a class");
        }
        Object[] args = evalCallArgs(fnArgsNode, context);
        if (context.isError()) {
            return Terms.UNDEFINED;
        }
        runSuperConstructor(active, context.thisObject, args, context);
        // A derived class's own instance fields init right after super() returns.
        runInstanceFieldInitializers(active, context.thisObject, context);
        return Terms.UNDEFINED; // the value of a super() call is unused as a statement
    }

    // The built-in constructors whose instances carry internal slots a plain
    // JsObject lacks, and whose state the super() shim can initialize in
    // place. `extends` on one of these makes `new` allocate the matching
    // exotic type (see allocateInstance). Error is deliberately absent — the
    // enumerable-prop copy-shim (message + stack) already covers it on a
    // plain JsObject. RegExp is absent because its compiled state is
    // immutable — `class X extends RegExp` stays on the copy-shim (exec/test

View on GitHub (pinned to a22eb90246)