karatelabs/karate · error · JsErrorException
Function.prototype.bind called on non-callable
Error message
Function.prototype.bind called on non-callable
What it means
Function.prototype.bind was invoked on a value that is not a JsCallable. bindMethod reads `this` from the context and, per §20.2.3.2, requires it to be a callable function; otherwise it throws a TypeError before constructing the bound function.
Solutions
- Check typeof target === 'function' before calling bind().
- Correct the variable/property so it actually references a function.
- Use an arrow function closure instead of bind if you control the call site.
- Guard with a default: `(target || function(){}).bind(this)` when a no-op is acceptable.
Example fix
// before
var bound = maybeFn.bind(this); // TypeError if maybeFn is not a function
// after
var bound = typeof maybeFn === 'function' ? maybeFn.bind(this) : function() {}; Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof target !== 'function') { throw new Error('bind target is not a function: ' + target); } Type guard
function isBindable(v) { return v != null && typeof v.bind === 'function' && typeof v === 'function'; } Try / catch
try { return target.bind(thisArg); } catch (e) { karate.log('bind failed on', target); return function() {}; } Prevention
- Guard optional callback parameters before binding
- Prefer arrow functions over bind when the target is known at write time
- Keep function-typed fields consistently typed through refactors
When it happens
Trigger: Calling someValue.bind(this) where someValue is undefined, null, a plain object, a number/string, or a Java-exposed object that is not a JS function; destructuring a method off an object and binding it when the lookup failed.
Common situations: Callback registration code where the callback variable was never assigned; using .bind defensively on something assumed to be a function; refactors that replaced a function-typed field with a non-function value.
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.apply 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/3356b0043d935e9d.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsFunctionPrototype.java:132
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");
}
Object boundThis = args.length > 0 ? args[0] : Terms.UNDEFINED;
Object[] preBound = args.length > 1
? Arrays.copyOfRange(args, 1, args.length)
: new Object[0];
JsFunction bound = new JsFunction() {
@Override
public Object call(Context ctx, Object[] callArgs) {
Object[] all;
if (preBound.length == 0) {
all = callArgs;
} else {
all = new Object[preBound.length + callArgs.length];
System.arraycopy(preBound, 0, all, 0, preBound.length);
System.arraycopy(callArgs, 0, all, preBound.length, callArgs.length);
}
if (ctx instanceof CoreContext cc) {
cc.thisObject = boundThis;View on GitHub (pinned to a22eb90246)