{"record":{"id":"5e1c0c5513da19ef","repo":"karatelabs/karate","slug":"reflect-construct-target-is-not-a-constructor","errorCode":null,"errorMessage":"Reflect.construct: target is not a constructor","messagePattern":"Reflect\\.construct: target is not a constructor","errorType":"exception","errorClass":"JsErrorException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JsReflect.java","lineNumber":79,"sourceCode":"            keys.addAll(jo.ownSymbols());\n        }\n        return new JsArray(keys);\n    }\n\n    @Override\n    protected Iterable<String> ownIntrinsicNames() {\n        return INTRINSIC_NAMES;\n    }\n\n    // Reflect.construct(target, argumentsList[, newTarget])\n    // Spec §28.1.2: throws TypeError if target or newTarget is not a constructor;\n    // dispatches Construct(target, args, newTarget). For our minimal version,\n    // newTarget mostly affects the result's [[Prototype]] — the test262\n    // isConstructor harness only cares whether the call throws, so we use\n    // newTarget purely as the constructable check when supplied.\n    private Object construct(Context context, Object[] args) {\n        if (args.length < 1 || !(args[0] instanceof JsCallable target)) {\n            throw JsErrorException.typeError(\"Reflect.construct: target is not a constructor\");\n        }\n        Object[] cArgs = listToArray(args.length >= 2 ? args[1] : null);\n        JsCallable check = target;\n        if (args.length >= 3) {\n            if (!(args[2] instanceof JsCallable nt)) {\n                throw JsErrorException.typeError(\"Reflect.construct: newTarget is not a constructor\");\n            }\n            check = nt;\n        }\n        if (!check.isConstructable()) {\n            throw JsErrorException.typeError(\"Reflect.construct: target is not a constructor\");\n        }\n        if (!(context instanceof CoreContext cc)) {\n            throw JsErrorException.typeError(\"Reflect.construct: bad context\");\n        }\n        return Interpreter.constructFromHost(target, cArgs, cc);\n    }\n","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JsReflect.java#L61-L97","documentation":"`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.","triggerScenarios":"`Reflect.construct()` with no target; `Reflect.construct(someObject, [])`; `Reflect.construct(arrowFn, [])` (arrows aren't constructable); passing a non-constructable built-in.","commonSituations":"Dynamic class instantiation from configuration where the target lookup resolved to undefined or an arrow function; reflection-based factories over non-constructable values.","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."],"exampleFix":"// before\nconst instance = Reflect.construct(arrowFactory, [opts]); // arrow is not constructable\n// after\nfunction Factory(opts) { this.opts = opts; }\nconst instance = Reflect.construct(Factory, [opts]);","handlingStrategy":"type-guard","validationCode":"function safeConstruct(Target, args) {\n  if (typeof Target !== 'function' || !Target.prototype) throw new TypeError('target must be a constructor');\n  return Reflect.construct(Target, args);\n}","typeGuard":"function isConstructableFn(v) { return typeof v === 'function' && !!v.prototype; }","tryCatchPattern":"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; }","preventionTips":["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."],"tags":["javascript","reflect","constructor"],"backgroundTag":"invalid-argument-value","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}