{"record":{"id":"0cfbc50b5f346eac","repo":"petkaantonov/bluebird","slug":"object-s-has-no-method-s","errorCode":null,"errorMessage":"Object %s has no method '%s'","messagePattern":"Object (.+?) has no method '(.+?)'","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/call_get.js","lineNumber":75,"sourceCode":"    return ret;\n};\n\ngetMethodCaller = function(name) {\n    return getCompiled(name, makeMethodCaller, callerCache);\n};\n\ngetGetter = function(name) {\n    return getCompiled(name, makeGetter, getterCache);\n};\n}\n\nfunction ensureMethod(obj, methodName) {\n    var fn;\n    if (obj != null) fn = obj[methodName];\n    if (typeof fn !== \"function\") {\n        var message = \"Object \" + util.classString(obj) + \" has no method '\" +\n            util.toString(methodName) + \"'\";\n        throw new Promise.TypeError(message);\n    }\n    return fn;\n}\n\nfunction caller(obj) {\n    var methodName = this.pop();\n    var fn = ensureMethod(obj, methodName);\n    return fn.apply(obj, this);\n}\nPromise.prototype.call = function (methodName) {\n    INLINE_SLICE(args, arguments, 1);\n    if (!__BROWSER__) {\n        if (canEvaluate) {\n            var maybeCaller = getMethodCaller(methodName);\n            if (maybeCaller !== null) {\n                return this._then(\n                    maybeCaller, undefined, undefined, args, undefined);\n            }","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/petkaantonov/bluebird/blob/c220cfe480868e2f5c5de4fe8bb3b04b97588d7f/src/call_get.js#L57-L93","documentation":"Bluebird's .call()/.get() helpers call a named method on the resolved value. ensureMethod looks up obj[methodName] and throws a Promise.TypeError when the property is missing or not a function, with the message 'Object %s has no method %s'. It protects you from an obscure 'undefined is not a function' later inside the promise chain.","triggerScenarios":"promise.call('methodName') or promise.get('methodName') where the resolved object either lacks the property or holds a non-function value — e.g. chaining .call('save') on a plain object, or the resolved value changed shape (null/undefined/array) from an API response.","commonSituations":"Refactors that rename or remove a method while promise chains still reference the old name; calling .get on an object whose property is data not a function; resolving JSON deserialized from HTTP where methods don't exist; typos in method names.","solutions":["Log or inspect the resolved object to confirm its shape before .call/.get","Use .then(obj => obj.method(...)) with an existence check instead of .call","Fix the method name typo or restore the removed method","Guard with typeof obj === 'object' && typeof obj.method === 'function' upstream","Ensure the value you expected (a class instance with methods) is actually resolved, not plain JSON"],"exampleFix":"// before\ngetUser().call('save');\n// after\ngetUser().then(user => {\n  if (typeof user.save !== 'function') throw new Error('user has no save()');\n  return user.save();\n});","handlingStrategy":"type-guard","validationCode":"function canCallAnd(obj, methodName) {\n  return obj != null && typeof obj[methodName] === 'function';\n}\nif (!canCallAnd(value, 'save')) throw new TypeError('value.save is not a function');","typeGuard":"function hasMethod(obj, name) {\n  return typeof obj === 'object' && obj !== null &&\n    typeof obj[name] === 'function';\n}","tryCatchPattern":"promise\n  .then(obj => {\n    if (typeof obj.save !== 'function') throw new TypeError('no save() on ' + util.inspect(obj));\n    return obj.save();\n  })\n  .catch(TypeError, e => { console.error(e.message); return fallback; });","preventionTips":["Prefer explicit .then(obj => obj.method()) over .call/.get so shape errors are local","Validate resolved object shape when consuming external/JSON data","Keep method names in constants shared with the producing module","Add runtime shape checks at API boundaries"],"tags":["typeerror","promise-chaining","method-missing"],"backgroundTag":"undefined-is-not-a-function","analyzedSha":"c220cfe480868e2f5c5de4fe8bb3b04b97588d7f","analyzedAt":"2026-09-02T02:30:20.863Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}