karatelabs/karate · error · JsErrorException
super: parent class is not a constructor
Error message
super: parent class is not a constructor
What it means
Thrown when running a derived constructor's `super(...)` but the derived class's prototype (its [[Prototype]], set to the superclass at class-eval time) is not a constructable JsCallable. This happens when the extends chain was corrupted or the parent was replaced with a non-constructor value.
Solutions
- Do not reassign the parent class binding after the derived class is declared.
- Re-derive the child class from a valid constructor: `class Child extends ValidParent {}`.
- Check for Object.setPrototypeOf calls or factory code that replaced the parent with a plain object.
Example fix
// before
let Parent = {};
class Child extends Parent {}
// after
class Parent {}
class Child extends Parent {} Defensive patterns
Strategy: validation
Validate before calling
if (typeof ParentClass !== 'function') throw new Error('parent class must be a constructable function'); Type guard
function isClassLike(v) { return typeof v === 'function' && v.prototype && v.prototype.constructor === v; } Try / catch
try { var c = new Child(); } catch (e) { if (String(e).includes('parent class is not a constructor')) restoreParent(); } Prevention
- Never reassign class bindings after declaration
- Avoid Object.setPrototypeOf on constructors
- Define inheritance chains in one place
When it happens
Trigger: Instantiating a derived class whose parent class reference was overwritten with a non-constructable value, or whose [[Prototype]] was mutated (e.g. Object.setPrototypeOf) to a non-callable.
Common situations: Monkey-patching or reassigning a class binding after definition; circular or partially-initialized class definitions where the parent ended up undefined or an object.
Related errors
- 'super' keyword is only valid inside a class method
- cannot create property
- cannot set property on null 'super' base
- Class constructor cannot be invoked without 'new
- Class extends value is not a constructor or null
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/3c9ed2e92d15b62b.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/Interpreter.java:1436
}
if (thisObj instanceof JsSet dst && built instanceof JsSet src) {
dst.elements.putAll(src.elements);
return true;
}
if (thisObj instanceof JsDate dst && built instanceof JsDate src) {
dst.setTimeValue(src.getTimeValue());
return true;
}
return false;
}
// Runs the parent constructor of {@code derivedCtor} against an existing
// instance ({@code thisObj}) — the derived `this`. The parent is the derived
// constructor's [[Prototype]] (set to the superclass at class-eval time).
static void runSuperConstructor(JsFunctionNode derivedCtor, Object thisObj, Object[] args, CoreContext context) {
Object parent = derivedCtor.getPrototype(); // Child.__proto__ === Parent
if (!(parent instanceof JsCallable parentCallable) || !parentCallable.isConstructable()) {
throw JsErrorException.typeError("super: parent class is not a constructor");
}
if (parent instanceof JsFunctionNode parentFn) {
CoreContext sc = new CoreContext(context, parentFn.node, args,
parentFn.declaredContext, parentFn.capturedBindings);
sc.strict = parentFn.strict;
sc.thisObject = thisObj;
sc.activeFunction = parentFn;
sc.callInfo = new CallInfo(true, parentFn);
sc.privateEnv = parentFn.privateEnv;
// If the parent is itself a derived class with an implicit
// constructor, forward up the chain before running its (empty) body.
// Either way the parent's own instance fields (and private brands) are
// its responsibility, on the same before-body / after-super schedule the
// top-level construction path uses; a parent with an explicit derived
// constructor runs them from its own super() call instead.
if (parentFn.isDefaultDerivedConstructor) {
runSuperConstructor(parentFn, thisObj, args, sc);
runInstanceFieldInitializers(parentFn, thisObj, sc);View on GitHub (pinned to a22eb90246)