jashkenas/underscore · error · TypeError
Bind must be called on a function
Error message
Bind must be called on a function
What it means
_.bind (and its OO counterpart) requires its first argument to be an actual function, since it creates a new function wrapping it. The library checks the argument with isFunction and throws a TypeError when it is not, because there is no meaningful way to bind a non-callable value.
Source
Thrown at modules/bind.js:8
import restArguments from './restArguments.js';
import isFunction from './isFunction.js';
import executeBound from './_executeBound.js';
// Create a function bound to a given object (assigning `this`, and arguments,
// optionally).
export default restArguments(function(func, context, args) {
if (!isFunction(func)) throw new TypeError('Bind must be called on a function');
var bound = restArguments(function(callArgs) {
return executeBound(func, bound, context, this, args.concat(callArgs));
});
return bound;
});
View on GitHub (pinned to e70d5bd070)
Solutions
- Log or console.log the value passed as the first argument to _.bind right before the call to see what it actually is (undefined, null, object, etc.).
- Check that the method name/key you resolve to a function actually exists on the object (use obj.hasOwnProperty or a default).
- Fix misspelled method names or restore the deleted/renamed function being bound.
- Verify the import: ensure you imported the function itself, not a namespace/module object.
- If the value may legitimately be absent, guard with typeof v === 'function' before binding.
Example fix
// before
_.bind(obj.onComplete, obj);
// TypeError: Bind must be called on a function
// after
if (typeof obj.onComplete === 'function') {
_.bind(obj.onComplete, obj);
} Defensive patterns
Strategy: type-guard
Validate before calling
function assertBindable(fn) {
if (typeof fn !== 'function') {
throw new TypeError('_.bind requires a function, got: ' + typeof fn);
}
}
// call before: assertBindable(obj.onComplete); _.bind(obj.onComplete, obj); Type guard
const isBindable = (v) => typeof v === 'function';
Try / catch
try {
const bound = _.bind(maybeFn, ctx);
return bound;
} catch (e) {
if (e instanceof TypeError && /Bind must be called on a function/.test(e.message)) {
return _.noop; // or log and fall back
}
throw e;
} Prevention
- Always typeof-check the value before _.bind, especially for dynamically resolved method names.
- Use optional chaining/default parameters for optional callbacks: typeof cb === 'function' ? _.bind(cb, ctx) : null.
- Keep object method names in one constants module to avoid typo drift between definition and bindAll/bind call sites.
- Verify your bundler/import setup so a module namespace object is not accidentally passed instead of the exported function.
- Add a unit test for each dynamically-resolved handler to assert it is a function.
When it happens
Trigger: Calling _.bind with a non-function first argument, e.g. _.bind(undefined, obj), _.bind(obj.methodName, obj) when the method name is misspelled or the property is undefined/null, or passing a string/number/array instead of a function.
Common situations: Refactoring renamed or deleted an object method while call sites still reference it; a lookup like handlers[name] returns undefined because the registry key doesn't exist; destructured or optional callback arguments are undefined when the caller omits them; CommonJS/ESM import mistakes yield the wrong export object instead of a function.
Related errors
AI-assisted analysis of jashkenas/underscore@e70d5bd070 (2026-08-29).
Data as JSON: /api/errors/64565c97b38ccd66.
Report an issue: GitHub.