jashkenas/underscore · error · Error
bindAll must be passed function names
Error message
bindAll must be passed function names
What it means
_.bindAll binds each named method of an object to that object; the method names come from the remaining rest arguments. If, after flattening, no keys were supplied at all, there is nothing to bind, so the library throws. This is almost always a call-site mistake rather than a data problem.
Source
Thrown at modules/bindAll.js:11
import restArguments from './restArguments.js';
import flatten from './_flatten.js';
import bind from './bind.js';
// Bind a number of an object's methods to that object. Remaining arguments
// are the method names to be bound. Useful for ensuring that all callbacks
// defined on an object belong to it.
export default restArguments(function(obj, keys) {
keys = flatten(keys, false, false);
var index = keys.length;
if (index < 1) throw new Error('bindAll must be passed function names');
while (index--) {
var key = keys[index];
obj[key] = bind(obj[key], obj);
}
return obj;
});
View on GitHub (pinned to e70d5bd070)
Solutions
- Pass at least one method name: _.bindAll(obj, 'method1', 'method2') or an array _.bindAll(obj, names).
- Verify the variable holding the names array is non-empty at the call site (console.log(names) before the call).
- Fix the upstream filter/derivation that produced an empty list of names.
- If names can legitimately be empty, skip the call when names.length === 0 instead of invoking bindAll.
- Consider whether you intended to spread the array: _.bindAll(obj, ...names) instead of _.bindAll(obj, names) (both work here due to internal flatten, but an empty array in either form still throws).
Example fix
// before
_.bindAll(view, view.eventNames); // eventNames is []
// Error: bindAll must be passed function names
// after
if (view.eventNames.length > 0) {
_.bindAll(view, view.eventNames);
} Defensive patterns
Strategy: validation
Validate before calling
function safeBindAll(obj, names) {
const flat = names.flat(Infinity);
if (!Array.isArray(names) || flat.length === 0) return obj; // nothing to bind
return _.bindAll(obj, ...flat);
} Type guard
const hasNamesToBind = (names) => Array.isArray(names) && names.flat(Infinity).length > 0;
Try / catch
try {
return _.bindAll(obj, ...names);
} catch (e) {
if (e instanceof Error && /bindAll must be passed function names/.test(e.message)) {
return obj; // binding zero methods is a no-op
}
throw e;
} Prevention
- Guard the names list length before calling bindAll: if (names.length) _.bindAll(obj, ...names).
- Avoid building the method-name list with filters that can silently return [].
- Default to an explicit set of method names in source rather than deriving them at runtime.
- Remember bindAll throws on an empty list — treat it as a required argument.
- Write a test that calls bindAll with the real name list to catch regressions where it becomes empty.
When it happens
Trigger: Calling _.bindAll(obj) with no method-name arguments, or _.bindAll(obj, []) or _.bindAll(obj, [], []) — any call whose flattened rest-argument list has length 0.
Common situations: Spreading a possibly-empty array of names: _.bindAll(obj, ...names); building the method-name list dynamically from a filter that matched nothing; migrating from code where defaults filled in the names and the defaults were removed; copying an example and forgetting to replace placeholder method names.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
AI-assisted analysis of jashkenas/underscore@e70d5bd070 (2026-08-29).
Data as JSON: /api/errors/e4cfad7d6914d86c.
Report an issue: GitHub.