karatelabs/karate · error · JsErrorException
Function.prototype.apply called on non-callable
Error message
Function.prototype.apply called on non-callable
What it means
Function.prototype.apply was invoked on a value that is not a callable (function). Karate's JS engine implements Function.prototype.apply in JsFunctionPrototype.applyMethod, and per the ECMAScript spec it first coerces `this` to a callable; if that coercion fails (asCallable returns null) it throws a TypeError instead of failing later inside the interpreter.
Solutions
- Print/inspect the value before calling apply and confirm it is a function (typeof fn === 'function').
- Fix the reference so it points at the actual function instead of a call result or property lookup that returned undefined.
- Use call() or spread (...) syntax instead if you do not need the apply argument-array semantics.
- Wrap the invocation in try/catch if the callable is genuinely optional at runtime.
Example fix
// before
var handler = config.handlers[name];
handler.apply(null, args); // handler may be undefined
// after
var handler = config.handlers[name];
if (typeof handler === 'function') {
handler.apply(null, args);
} else {
karate.log('no handler for', name);
} Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof fn !== 'function') { throw new Error('expected callable, got: ' + fn); } Type guard
function isCallable(v) { return typeof v === 'function'; } Try / catch
try { fn.apply(thisArg, args); } catch (e) { if (String(e).indexOf('non-callable') !== -1) { karate.log('not a function:', fn); } else { throw e; } } Prevention
- Always verify typeof === 'function' before apply/call/bind on dynamic references
- Avoid naming collisions that shadow function-valued variables with their results
- Wrap Java-side values and confirm they are exposed as JS functions before treating them as callables
When it happens
Trigger: Calling fn.apply(...) where `fn` is undefined, null, a plain object, a primitive, or a non-function value that reached the Function prototype (e.g. a method borrowed from the wrong object, or a typo like `myfunc.aply` resolving through a proxy).
Common situations: Refactoring code where a variable that used to hold a function now holds its result; calling .apply on a Java-side value exposed to JS that is not wrapped as a JsCallable; duck-typed code assuming an object has a method that is actually missing.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Function.prototype.bind called on non-callable
- argumentsList must be an iterable object
- assignment to constant
- assignment to constant
- called on null or undefined
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/8e9ab654573424ae.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsFunctionPrototype.java:115
// Spec OrdinaryCallBindThis (§9.2.1.2): the null/undefined → globalThis
// substitution applies to sloppy-mode user-defined functions only.
// Built-in methods and strict-mode user fns see the raw thisArg —
// required for e.g. Object.prototype.toString.call(null) returning
// "[object Null]" and for RequireObjectCoercible-gated built-ins to throw
// TypeError on null/undefined receivers.
private static Object bindForCall(JsCallable callable, Object thisObject, CoreContext cc) {
if (callable instanceof JsBuiltinMethod) {
return thisObject;
}
boolean strict = callable instanceof JsFunctionNode jfn && jfn.strict;
return Interpreter.bindThisForCall(thisObject, cc, strict);
}
private Object applyMethod(Context context, Object[] args) {
JsCallable callable = asCallable(context);
if (callable == null) {
throw JsErrorException.typeError("Function.prototype.apply called on non-callable");
}
ThisArgs thisArgs = new ThisArgs(args, true);
if (context instanceof CoreContext cc) {
cc.thisObject = bindForCall(callable, thisArgs.thisObject, cc);
}
return callable.call(context, thisArgs.args.toArray(new Object[0]));
}
// Spec: Function.prototype.bind(thisArg, ...preBound) returns a new callable
// that, when invoked, calls the target with `this` set to thisArg and
// arguments = preBound concat actualArgs. Pre-bound args win in order.
// Per §20.2.3.2 the bound function's `length` is
// max(0, target.length - preBound.length).
private Object bindMethod(Context context, Object[] args) {
Object thisObj = context.getThisObject();
if (!(thisObj instanceof JsCallable target)) {
throw JsErrorException.typeError("Function.prototype.bind called on non-callable");
}View on GitHub (pinned to a22eb90246)