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

  1. Log or inspect the resolved object to confirm its shape before .call/.get
  2. Use .then(obj => obj.method(...)) with an existence check instead of .call
  3. Fix the method name typo or restore the removed method
  4. Guard with typeof obj === 'object' && typeof obj.method === 'function' upstream
  5. 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

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


AI-assisted analysis of petkaantonov/bluebird@c220cfe480 (2026-09-02). Data as JSON: /api/errors/0cfbc50b5f346eac. Report an issue: GitHub.