karatelabs/karate · error · JsErrorException

'super' keyword is only valid inside a class method

Error message

'super' keyword is only valid inside a class method

What it means

Thrown as a syntax error when `super.x` / `super[x]` is evaluated in a context with no active class function or no home object. `super.x` resolves via the [[Prototype]] of the enclosing method's home object; without a class method context there is nothing to resolve against.

Solutions

  1. Keep `super.x` calls inside class methods (or object-literal shorthand methods bound to a home object).
  2. Capture the parent reference explicitly (e.g. `const parent = Parent.prototype`) and call `parent.method.call(this)` when extracting code.
  3. Assign the extracted function as a class method if super-property access is required.

Example fix

// before
function describe() { return super.describe(); }
// after
class Child extends Parent {
  describe() { return super.describe(); }
}
Defensive patterns

Strategy: validation

Try / catch

try { obj.copiedMethod(); } catch (e) { if (String(e).includes("'super' keyword")) { /* rebind as class method */ } }

Prevention

When it happens

Trigger: Using `super.someMethod()` inside a plain function, arrow function defined outside a class method, object-literal method, or top-level code.

Common situations: Moving a class method body into a standalone helper while keeping its `super.` calls; destructuring a method off a class and calling it elsewhere.

Related errors


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

Appendix: source

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

            Object value = evalFieldInitializer(f.initializer, thisObj, context);
            if (context.isError()) {
                return;
            }
            if (f.privateName == null) {
                obj.putMember(f.key, value); // public fields are enumerable own properties
            } else {
                obj.putPrivate(f.privateName, value);
            }
        }
    }

    // Resolves the property-lookup target for `super.x` / `super[x]`: the
    // [[Prototype]] of the active method's home object (the parent class's
    // prototype, or the parent constructor for a static method).
    static ObjectLike evalSuperBase(CoreContext context) {
        JsFunctionNode active = context.activeFunction;
        if (active == null || active.homeObject == null) {
            throw JsErrorException.syntaxError("'super' keyword is only valid inside a class method");
        }
        ObjectLike home = active.homeObject;
        Object proto = home.getPrototype();
        return proto instanceof ObjectLike ol ? ol : null;
    }

    // Resolved shape of a CLASS_METHOD node. Methods/accessors end in FN_EXPR;
    // fields have no FN_EXPR (optional trailing [EQ, EXPR] initializer):
    //   [modifier tokens...] <key (1 name token | L_BRACKET EXPR R_BRACKET)>
    //       ( FN_EXPR | [EQ EXPR]? )
    private static final class ClassMember {
        boolean isStatic;
        boolean isAccessor;
        boolean isField;
        boolean isPrivate;  // key was a `#name` token
        PrivateName privateName; // resolved identity, when private
        String kind;        // "get" / "set" / null
        boolean computed;

View on GitHub (pinned to a22eb90246)