petkaantonov/bluebird · error · TypeError

cannot get rejection reason of a non-rejected promise S

Error message

cannot get rejection reason of a non-rejected promise

    See http://goo.gl/MqrFmX

What it means

The `.reason()`/`.error()` accessor on PromiseInspection (src/synchronous_inspection.js:30) returns the rejection reason only when the underlying promise is rejected. Calling it on a fulfilled or pending inspection throws this TypeError.

Source

Thrown at src/synchronous_inspection.js:30

        this._settledValueField = undefined;
    }
}

PromiseInspection.prototype._settledValue = function() {
    return this._settledValueField;
};

var value = PromiseInspection.prototype.value = function () {
    if (!this.isFulfilled()) {
        throw new TypeError(INSPECTION_VALUE_ERROR);
    }
    return this._settledValue();
};

var reason = PromiseInspection.prototype.error =
PromiseInspection.prototype.reason = function () {
    if (!this.isRejected()) {
        throw new TypeError(INSPECTION_REASON_ERROR);
    }
    return this._settledValue();
};

var isFulfilled = PromiseInspection.prototype.isFulfilled = function() {
    return (this._bitField & IS_FULFILLED) !== 0;
};

var isRejected = PromiseInspection.prototype.isRejected = function () {
    return (this._bitField & IS_REJECTED) !== 0;
};

var isPending = PromiseInspection.prototype.isPending = function () {
    return (this._bitField & IS_REJECTED_OR_FULFILLED_OR_CANCELLED) === 0;
};

var isResolved = PromiseInspection.prototype.isResolved = function () {
    return (this._bitField & IS_REJECTED_OR_FULFILLED) !== 0;

View on GitHub (pinned to c220cfe480)

Solutions

  1. Guard with `insp.isRejected()` before calling `.reason()`.
  2. Branch symmetrically: `isFulfilled() ? insp.value() : insp.reason()`.
  3. For aggregate reporting, normalize each inspection into a result object first.

Example fix

// before
results.map(insp => insp.reason());
// after
results.map(insp => insp.isRejected() ? insp.reason() : null);
Defensive patterns

Strategy: type-guard

Validate before calling

const readReason = (insp) => {
  if (!insp.isRejected()) throw new TypeError('reason() requires a rejected inspection');
  return insp.reason();
};

Type guard

const readIfRejected = (insp) => insp.isRejected() ? { rejected: true, reason: insp.reason() } : { rejected: false };

Try / catch

p.reflect().then(insp => {
  let err;
  try { err = insp.reason(); } catch (e) {
    err = insp.isFulfilled() ? insp.value() : null;
  }
  return err;
});

Prevention

When it happens

Trigger: `promise.reflect().then(insp => insp.reason())` when the promise fulfilled; calling `.reason()` on `Promise.inspect(p)` while p is still pending.

Common situations: Error-reporting pipelines over `allSettled`-style reflect results that unconditionally read `.reason()`; mixing up `.value()`/`.reason()` branches.

Related errors


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