{"record":{"id":"b8365d165ddbe8a6","repo":"karatelabs/karate","slug":"reflect-construct-newtarget-is-not-a-constructor","errorCode":null,"errorMessage":"Reflect.construct: newTarget is not a constructor","messagePattern":"Reflect\\.construct: newTarget is not a constructor","errorType":"exception","errorClass":"JsErrorException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JsReflect.java","lineNumber":85,"sourceCode":"    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\n    // Reflect.apply(target, thisArgument, argumentsList) — spec §28.1.1.\n    private Object apply(Context context, Object[] args) {\n        if (args.length < 1 || !(args[0] instanceof JsCallable target)) {\n            throw JsErrorException.typeError(\"Reflect.apply: target is not callable\");\n        }\n        Object thisArg = args.length >= 2 ? args[1] : Terms.UNDEFINED;","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JsReflect.java#L67-L103","documentation":"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.","triggerScenarios":"`Reflect.construct(Target, args, notAFunction)` — e.g. passing an object, a primitive, or an undefined variable as newTarget.","commonSituations":"Metaprogramming that computes newTarget dynamically (subclass registries, plugin systems) where the lookup returned a non-function; typos in the third argument.","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."],"exampleFix":"// before\nconst obj = Reflect.construct(Base, args, registry[name]); // registry entry missing -> undefined\n// after\nconst NT = registry[name];\nconst obj = typeof NT === 'function' ? Reflect.construct(Base, args, NT) : Reflect.construct(Base, args);","handlingStrategy":"validation","validationCode":"function safeConstructWithTarget(Target, args, NewTarget) {\n  const useNT = typeof NewTarget === 'function' && NewTarget.prototype;\n  return useNT ? Reflect.construct(Target, args, NewTarget) : Reflect.construct(Target, args);\n}","typeGuard":"function isValidNewTarget(v) { return v != null && typeof v === 'function' && !!v.prototype; }","tryCatchPattern":"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; }","preventionTips":["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."],"tags":["javascript","reflect","constructor","new-target"],"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"}