karatelabs/karate · error · TypeError
Reflect.construct: bad context
Error message
Reflect.construct: bad context
What it means
After validating the target/newTarget are constructable, JsReflect.construct requires the active interpreter Context to be an instance of CoreContext so it can dispatch Interpreter.constructFromHost. If the surrounding Context is some other Context implementation, a TypeError 'Reflect.construct: bad context' is thrown. This is effectively an internal invariant violation — normal Karate JS evaluation always provides a CoreContext.
Solutions
- Run the script through the standard Karate JS engine entry point so a CoreContext is active
- If embedding, ensure the Context passed to JsCallable.call is the engine's CoreContext, not a custom subclass/wrapper
- Upgrade or re-align custom Context implementations after engine version changes
Defensive patterns
Strategy: validation
Validate before calling
// Host-side check before invoking the engine builtin:
if (!(context instanceof io.karatelabs.js.CoreContext)) {
throw new IllegalStateException('Reflect.construct requires a CoreContext');
} Type guard
if (!(context instanceof io.karatelabs.js.CoreContext cc)) {
throw new IllegalStateException('bad context: ' + context.getClass().getName());
} Try / catch
try {
return Reflect_construct(ctx, args);
} catch (JsErrorException e) {
if (e.getMessage().contains("bad context")) {
// re-run through the standard engine entry point
return engine.eval(scriptWithContextFixed);
}
throw e;
} Prevention
- Always evaluate scripts through the standard Karate JS engine entry points
- Do not pass custom Context implementations into JsCallable.call for builtins
- Re-validate custom embedding code after upgrading karate-js
- Keep host-object callbacks receiving the engine-provided Context unchanged
When it happens
Trigger: Calling Reflect.construct from a context where `context instanceof CoreContext` is false — e.g. embedding the Karate JS engine and invoking builtins with a custom/minimal Context implementation rather than the engine's CoreContext.
Common situations: Embedding karate-js in a host application with a hand-rolled Context; calling engine internals reflectively or from a custom host-object callback that supplies its own Context; version drift where a custom Context was written against an older engine that did not require CoreContext here.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Reflect.ownKeys called on non-object
- Reflect.construct: target is not a constructor
- Reflect.construct: newTarget is not a constructor
- Reflect.apply: target is not callable
- argumentsList must be an iterable object
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/16ea3a7a9cdbe7ea.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsReflect.java:93
// 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;
Object[] cArgs = listToArray(args.length >= 3 ? args[2] : null);
if (context instanceof CoreContext cc) {
cc.thisObject = thisArg;
}
return target.call(context, cArgs);
}
private static Object[] listToArray(Object value) {View on GitHub (pinned to a22eb90246)