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

  1. 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.).
  2. Check that the method name/key you resolve to a function actually exists on the object (use obj.hasOwnProperty or a default).
  3. Fix misspelled method names or restore the deleted/renamed function being bound.
  4. Verify the import: ensure you imported the function itself, not a namespace/module object.
  5. 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

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.