{"record":{"id":"f237e9f3f46010a2","repo":"petkaantonov/bluebird","slug":"the-last-argument-to-catch-must-be-a-function","errorCode":null,"errorMessage":"The last argument to .catch() must be a function, got %s","messagePattern":"The last argument to \\.catch\\(\\) must be a function, got (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/promise.js","lineNumber":131,"sourceCode":"Promise.prototype.caught = Promise.prototype[\"catch\"] = function (fn) {\n    var len = arguments.length;\n    if (len > 1) {\n        var catchInstances = new Array(len - 1),\n            j = 0, i;\n        for (i = 0; i < len - 1; ++i) {\n            var item = arguments[i];\n            if (util.isObject(item)) {\n                catchInstances[j++] = item;\n            } else {\n                return apiRejection(\"Catch statement predicate: \" +\n                    OBJECT_ERROR + util.classString(item));\n            }\n        }\n        catchInstances.length = j;\n        fn = arguments[i];\n\n        if (typeof fn !== \"function\") {\n            throw new TypeError(\"The last argument to .catch() \" +\n                \"must be a function, got \" + util.toString(fn));\n        }\n        return this.then(undefined, catchFilter(catchInstances, fn, this));\n    }\n    return this.then(undefined, fn);\n};\n\nPromise.prototype.reflect = function () {\n    return this._then(reflectHandler,\n        reflectHandler, undefined, this, undefined);\n};\n\nPromise.prototype.then = function (didFulfill, didReject) {\n    if (debug.warnings() && arguments.length > 0 &&\n        typeof didFulfill !== \"function\" &&\n        typeof didReject !== \"function\") {\n        var msg = \".then() only accepts functions but was passed: \" +\n                util.classString(didFulfill);","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/petkaantonov/bluebird/blob/c220cfe480868e2f5c5de4fe8bb3b04b97588d7f/src/promise.js#L113-L149","documentation":"`.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.","triggerScenarios":"`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).","commonSituations":"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.","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())`."],"exampleFix":"// before\npromise.catch(TypeError, err.message => console.log);\n// after\npromise.catch(TypeError, (err) => console.log(err.message));","handlingStrategy":"validation","validationCode":"function safeCatch(p, ...args) {\n  const last = args[args.length - 1];\n  if (typeof last !== 'function') throw new TypeError('.catch() last argument must be a function');\n  return p.catch(...args);\n}","typeGuard":"const isHandler = (v) => typeof v === 'function';","tryCatchPattern":"try { p = p.catch(TypeError, handler); } catch (e) {\n  if (String(e).includes('must be a function')) p = p.catch(defaultHandler);\n  else throw e;\n}","preventionTips":["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."],"tags":["typeerror","catch","api-misuse"],"backgroundTag":"promise-catch-requires-function","analyzedSha":"c220cfe480868e2f5c5de4fe8bb3b04b97588d7f","analyzedAt":"2026-09-02T02:30:20.863Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}