karatelabs/karate · error · JsErrorException
Reflect.construct: newTarget is not a constructor
Error message
Reflect.construct: newTarget is not a constructor
What it means
When `Reflect.construct` is given a third argument (newTarget), the engine verifies it is a JsCallable and a valid constructor, since newTarget determines the result's [[Prototype]]. Passing a present-but-non-callable third argument throws this TypeError before any construction happens.
Solutions
- Pass a constructable function/class as newTarget, or omit the third argument to reuse target.
- Guard: `if (newTarget && typeof newTarget === 'function') Reflect.construct(T, a, newTarget) else Reflect.construct(T, a)`.
- Verify the subclass registry entry actually holds a class, not an instance.
Example fix
// before const obj = Reflect.construct(Base, args, registry[name]); // registry entry missing -> undefined // after const NT = registry[name]; const obj = typeof NT === 'function' ? Reflect.construct(Base, args, NT) : Reflect.construct(Base, args);
Defensive patterns
Strategy: validation
Validate before calling
function safeConstructWithTarget(Target, args, NewTarget) {
const useNT = typeof NewTarget === 'function' && NewTarget.prototype;
return useNT ? Reflect.construct(Target, args, NewTarget) : Reflect.construct(Target, args);
} Type guard
function isValidNewTarget(v) { return v != null && typeof v === 'function' && !!v.prototype; } Try / catch
try { return Reflect.construct(T, a, NT); } catch (e) { if (e instanceof TypeError && /newTarget is not a constructor/.test(e.message)) return Reflect.construct(T, a); throw e; } Prevention
- Guard registry entries used as newTarget with typeof checks.
- Omit newTarget when you don't need custom [[Prototype]] semantics.
- Unit-test dynamic subclass resolution to ensure functions, not values, are returned.
When it happens
Trigger: `Reflect.construct(Target, args, notAFunction)` — e.g. passing an object, a primitive, or an undefined variable as newTarget.
Common situations: Metaprogramming that computes newTarget dynamically (subclass registries, plugin systems) where the lookup returned a non-function; typos in the third argument.
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
- Reflect.construct: target is not a constructor
- is not a constructor
- Class constructor cannot be invoked without 'new
- is not a constructor
- is not a constructor
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/b8365d165ddbe8a6.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsReflect.java:85
protected Iterable<String> ownIntrinsicNames() {
return INTRINSIC_NAMES;
}
// Reflect.construct(target, argumentsList[, newTarget])
// Spec §28.1.2: throws TypeError if target or newTarget is not a constructor;
// dispatches Construct(target, args, newTarget). For our minimal version,
// newTarget mostly affects the result's [[Prototype]] — the test262
// isConstructor harness only cares whether the call throws, so we use
// newTarget purely as the constructable check when supplied.
private Object construct(Context context, Object[] args) {
if (args.length < 1 || !(args[0] instanceof JsCallable target)) {
throw JsErrorException.typeError("Reflect.construct: target is not a constructor");
}
Object[] cArgs = listToArray(args.length >= 2 ? args[1] : null);
JsCallable check = target;
if (args.length >= 3) {
if (!(args[2] instanceof JsCallable nt)) {
throw JsErrorException.typeError("Reflect.construct: newTarget is not a constructor");
}
check = nt;
}
if (!check.isConstructable()) {
throw JsErrorException.typeError("Reflect.construct: target is not a constructor");
}
if (!(context instanceof CoreContext cc)) {
throw JsErrorException.typeError("Reflect.construct: bad context");
}
return Interpreter.constructFromHost(target, cArgs, cc);
}
// Reflect.apply(target, thisArgument, argumentsList) — spec §28.1.1.
private Object apply(Context context, Object[] args) {
if (args.length < 1 || !(args[0] instanceof JsCallable target)) {
throw JsErrorException.typeError("Reflect.apply: target is not callable");
}
Object thisArg = args.length >= 2 ? args[1] : Terms.UNDEFINED;View on GitHub (pinned to a22eb90246)