karatelabs/karate · error · TypeError
Reflect.apply: target is not callable
Error message
Reflect.apply: target is not callable
What it means
Reflect.apply(target, thisArgument, argumentsList) requires the first argument to be a callable function (spec §28.1.1). Karate's JsReflect throws this TypeError when args is empty or args[0] is not a JsCallable — e.g. a number, string, object, or undefined was passed as the target.
Solutions
- Check the first argument is a function before calling: `typeof fn === 'function'`
- Fix typos/undefined variables in the target position
- Use Function.prototype.call/bind or `fn(...args)` only on confirmed callables
Example fix
// before
Reflect.apply(handlers[name], this, args); // handlers[name] may be undefined
// after
if (typeof handlers[name] !== 'function') throw new Error('no handler: ' + name);
Reflect.apply(handlers[name], this, args); Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof target !== 'function') throw new Error('Reflect.apply requires a callable target, got: ' + target); Type guard
const isCallable = v => typeof v === 'function';
if (!isCallable(target)) throw new Error('not callable: ' + target); Try / catch
try {
return Reflect.apply(target, thisArg, args);
} catch (e) {
if (String(e.message).includes('not callable')) {
throw new Error('Reflect.apply target is not a function: ' + String(target));
}
throw e;
} Prevention
- Check typeof fn === 'function' on dynamically resolved function names
- Watch for undefined targets after renames/imports changes
- Validate lookup-table handlers are all functions at startup
- Prefer fn.apply/fn.call directly so missing functions fail at the same site
When it happens
Trigger: Reflect.apply() with no arguments; Reflect.apply(fnName, ...) where fnName is undefined due to a typo or failed import; passing a non-callable like an object, string, or number as the first argument.
Common situations: Dynamic function lookup that returns undefined at runtime; refactoring that renamed a function but missed a Reflect.apply call site; passing `this` or a value from a lookup table that holds non-function members.
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
- argumentsList must be an iterable object
- Cannot set property ' ' which has only a getter
- assignment to constant
- assignment to constant
- Generator is already running
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/963a641e10bfa9b6.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsReflect.java:101
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) {
if (value == null || value == Terms.UNDEFINED) {
return new Object[0];
}
if (value instanceof List<?> list) {
return list.toArray();
}
if (value instanceof Object[] arr) {
return arr;View on GitHub (pinned to a22eb90246)