petkaantonov/bluebird · error · TypeError
Object %s has no method '%s'
Error message
Object %s has no method '%s'
What it means
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.
Source
Thrown at src/call_get.js:75
return ret;
};
getMethodCaller = function(name) {
return getCompiled(name, makeMethodCaller, callerCache);
};
getGetter = function(name) {
return getCompiled(name, makeGetter, getterCache);
};
}
function ensureMethod(obj, methodName) {
var fn;
if (obj != null) fn = obj[methodName];
if (typeof fn !== "function") {
var message = "Object " + util.classString(obj) + " has no method '" +
util.toString(methodName) + "'";
throw new Promise.TypeError(message);
}
return fn;
}
function caller(obj) {
var methodName = this.pop();
var fn = ensureMethod(obj, methodName);
return fn.apply(obj, this);
}
Promise.prototype.call = function (methodName) {
INLINE_SLICE(args, arguments, 1);
if (!__BROWSER__) {
if (canEvaluate) {
var maybeCaller = getMethodCaller(methodName);
if (maybeCaller !== null) {
return this._then(
maybeCaller, undefined, undefined, args, undefined);
}View on GitHub (pinned to c220cfe480)
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
Example fix
// before
getUser().call('save');
// after
getUser().then(user => {
if (typeof user.save !== 'function') throw new Error('user has no save()');
return user.save();
}); Defensive patterns
Strategy: type-guard
Validate before calling
function canCallAnd(obj, methodName) {
return obj != null && typeof obj[methodName] === 'function';
}
if (!canCallAnd(value, 'save')) throw new TypeError('value.save is not a function'); Type guard
function hasMethod(obj, name) {
return typeof obj === 'object' && obj !== null &&
typeof obj[name] === 'function';
} Try / catch
promise
.then(obj => {
if (typeof obj.save !== 'function') throw new TypeError('no save() on ' + util.inspect(obj));
return obj.save();
})
.catch(TypeError, e => { console.error(e.message); return fallback; }); Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- 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
- the promise constructor cannot be invoked directly See
AI-assisted analysis of petkaantonov/bluebird@c220cfe480 (2026-09-02).
Data as JSON: /api/errors/0cfbc50b5f346eac.
Report an issue: GitHub.