karatelabs/karate · error · JsErrorException
Reflect.construct: target is not a constructor
Error message
Reflect.construct: target is not a constructor
What it means
`Reflect.construct(target, args)` requires `target` to be a constructable function; the engine also re-checks constructability on `newTarget` when supplied. If args[0] is absent or not a JsCallable (or the effective constructor fails `isConstructable()`), this TypeError is thrown, matching the spec's IsConstructor check.
Solutions
- Pass a constructable function/class as target: `Reflect.construct(MyClass, args)`.
- Guard: `if (typeof Target === 'function' && Target.prototype) Reflect.construct(Target, args)`.
- If the target is an arrow function, convert to a regular function/class.
Example fix
// before
const instance = Reflect.construct(arrowFactory, [opts]); // arrow is not constructable
// after
function Factory(opts) { this.opts = opts; }
const instance = Reflect.construct(Factory, [opts]); Defensive patterns
Strategy: type-guard
Validate before calling
function safeConstruct(Target, args) {
if (typeof Target !== 'function' || !Target.prototype) throw new TypeError('target must be a constructor');
return Reflect.construct(Target, args);
} Type guard
function isConstructableFn(v) { return typeof v === 'function' && !!v.prototype; } Try / catch
try { return Reflect.construct(Target, args); } catch (e) { if (e instanceof TypeError && /target is not a constructor/.test(e.message)) return Target.apply(null, args); throw e; } Prevention
- Verify dynamic class lookups resolve to classes, not instances or arrows.
- Prefer `new Target(...args)` when newTarget semantics aren't needed.
- Lint against Reflect.construct with non-identifier first arguments.
When it happens
Trigger: `Reflect.construct()` with no target; `Reflect.construct(someObject, [])`; `Reflect.construct(arrowFn, [])` (arrows aren't constructable); passing a non-constructable built-in.
Common situations: Dynamic class instantiation from configuration where the target lookup resolved to undefined or an arrow function; reflection-based factories over non-constructable values.
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: newTarget 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/5e1c0c5513da19ef.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsReflect.java:79
keys.addAll(jo.ownSymbols());
}
return new JsArray(keys);
}
@Override
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);
}
View on GitHub (pinned to a22eb90246)