awslabs/llrt · error · TypeError

You must provide a Promise to expect() when using .rejects…

Error message

You must provide a Promise to expect() when using .rejects, not '${typeof wrapper}'.

What it means

This TypeError is thrown by JestChaiExpect when the `.rejects` modifier is used but the (possibly invoked) value given to expect() is not a Promise. For Jest compatibility, if the object is a function it is first called (`const wrapper = typeof obj === 'function' ? obj() : obj`), then checked for a `then` method. If neither the function's return value nor the object is thenable, the error is raised.

Solutions

  1. Pass a function that returns a rejected promise or the promise itself: expect(asyncFn()).rejects.toThrow(E).
  2. Make sure the function under test is async or returns a Promise.
  3. If the value never rejects, drop .rejects and use .toThrow on a wrapping () => { ... } function instead.

Example fix

// before
expect(() => syncFn()).rejects.toThrow('boom'); // syncFn returns non-promise
// after
expect(asyncFn()).rejects.toThrow('boom');
Defensive patterns

Strategy: type-guard

Validate before calling

const wrapper = typeof fnOrValue === 'function' ? fnOrValue() : fnOrValue;
if (!wrapper || typeof wrapper.then !== 'function') throw new TypeError('.rejects requires a Promise');

Type guard

function isPromiseLike(v) {
  return v !== null && typeof v.then === 'function';
}

Prevention

When it happens

Trigger: Calling expect(fnOrValue).rejects.toThrow(...) where fnOrValue is a plain object/value, or a function that returns a non-Promise (e.g. a sync function).

Common situations: Passing a synchronous function to .rejects expecting it to be wrapped like Jest's expect(fn).rejects, or the async function was changed to sync so calling it returns undefined.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of awslabs/llrt@742fc00b82 (2026-09-12). Data as JSON: /api/errors/f66b621dfa1028fa. Report an issue: GitHub.

Appendix: source

Thrown at llrt_core/src/modules/js/@llrt/expect/jest-expect.ts:582

      });

      return proxy;
    }
  );

  utils.addProperty(
    chai.Assertion.prototype,
    "rejects",
    function __VITEST_REJECTS__(this: any) {
      const error = new Error("rejects");
      utils.flag(this, "promise", "rejects");
      utils.flag(this, "error", error);
      const test: any = utils.flag(this, "vitest-test");
      const obj = utils.flag(this, "object");
      const wrapper = typeof obj === "function" ? obj() : obj; // for jest compat

      if (typeof wrapper?.then !== "function")
        throw new TypeError(
          `You must provide a Promise to expect() when using .rejects, not '${typeof wrapper}'.`
        );

      const proxy: any = new Proxy(this, {
        get: (target, key, receiver) => {
          const result = Reflect.get(target, key, receiver);

          if (typeof result !== "function")
            return result instanceof chai.Assertion ? proxy : result;

          return async (...args: any[]) => {
            const promise = wrapper.then(
              (value: any) => {
                const _error = new AssertionError(
                  `promise resolved "${utils.inspect(value)}" instead of rejecting`,
                  {
                    showDiff: true,
                    expected: new Error("rejected promise"),

View on GitHub (pinned to 742fc00b82)