petkaantonov/bluebird · error · TypeError
The last argument to .catch() must be a function, got %s
Error message
The last argument to .catch() must be a function, got %s
What it means
`.catch()` (the overload taking multiple predicates) requires its LAST argument to be a handler function; the preceding arguments are predicate values/constructors matched against the rejection reason. Bluebird throws this TypeError when the final argument is anything else, because there would be no handler to invoke.
Source
Thrown at src/promise.js:131
Promise.prototype.caught = Promise.prototype["catch"] = function (fn) {
var len = arguments.length;
if (len > 1) {
var catchInstances = new Array(len - 1),
j = 0, i;
for (i = 0; i < len - 1; ++i) {
var item = arguments[i];
if (util.isObject(item)) {
catchInstances[j++] = item;
} else {
return apiRejection("Catch statement predicate: " +
OBJECT_ERROR + util.classString(item));
}
}
catchInstances.length = j;
fn = arguments[i];
if (typeof fn !== "function") {
throw new TypeError("The last argument to .catch() " +
"must be a function, got " + util.toString(fn));
}
return this.then(undefined, catchFilter(catchInstances, fn, this));
}
return this.then(undefined, fn);
};
Promise.prototype.reflect = function () {
return this._then(reflectHandler,
reflectHandler, undefined, this, undefined);
};
Promise.prototype.then = function (didFulfill, didReject) {
if (debug.warnings() && arguments.length > 0 &&
typeof didFulfill !== "function" &&
typeof didReject !== "function") {
var msg = ".then() only accepts functions but was passed: " +
util.classString(didFulfill);View on GitHub (pinned to c220cfe480)
Solutions
- Ensure the last argument is a function: `promise.catch(TypeError, err => ...)`.
- If you only have one handler, call `.catch(fn)` with no predicates.
- Pass the function reference itself, not an invocation: `.catch(handleErr)` not `.catch(handleErr())`.
Example fix
// before promise.catch(TypeError, err.message => console.log); // after promise.catch(TypeError, (err) => console.log(err.message));
Defensive patterns
Strategy: validation
Validate before calling
function safeCatch(p, ...args) {
const last = args[args.length - 1];
if (typeof last !== 'function') throw new TypeError('.catch() last argument must be a function');
return p.catch(...args);
} Type guard
const isHandler = (v) => typeof v === 'function';
Try / catch
try { p = p.catch(TypeError, handler); } catch (e) {
if (String(e).includes('must be a function')) p = p.catch(defaultHandler);
else throw e;
} Prevention
- List predicates first, handler function always last.
- Pass function references, not invocations (`fn` not `fn()`).
- For a single handler, use the simple one-argument `.catch(fn)` form.
When it happens
Trigger: `promise.catch(TypeError, 'oops')` (string as last arg); `promise.catch(predicate, someVar)` where someVar is undefined or not a function; mistyping `.catch(errHandler)` as `.catch(errHandler())` (passing the result of calling the handler).
Common situations: Mistakenly using Node-style `.catch(code, handler)` conventions in browser code; forgetting the handler after listing error predicates; passing an async IIFE result instead of the function itself.
Related errors
- Object %s has no method '%s'
- onCancel must be a function, got: %s
- generatorFunction must be a function See http://goo.gl/
- expecting a function but got %s
- expecting a function but got %s
AI-assisted analysis of petkaantonov/bluebird@c220cfe480 (2026-09-02).
Data as JSON: /api/errors/f237e9f3f46010a2.
Report an issue: GitHub.