vitest-dev/vitest · 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

TypeError thrown by the 'rejects' property getter when the value passed to expect() (or the function's return value, for jest-compat function wrapping) is not thenable. .rejects requires a real Promise-like target; the wrapper is computed at line 1150 as typeof obj === 'function' ? obj() : obj.

Source

Thrown at packages/expect/src/jest-expect.ts:1159

  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: Test = utils.flag(this, 'vitest-test')
      const obj = utils.flag(this, 'object')
      const wrapper = typeof obj === 'function' ? obj() : obj // for jest compat

      if (utils.flag(this, 'poll')) {
        throw new SyntaxError(
          `expect.poll() is not supported in combination with .rejects`,
        )
      }

      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 (...args: any[]) => {
            utils.flag(this, '_name', key)
            const promise = Promise.resolve(wrapper).then(
              (value: any) => {
                const _error = new AssertionError(
                  `promise resolved "${utils.inspect(

View on GitHub (pinned to d568f8ce37)

Solutions

  1. Ensure expect() receives a thenable: expect(promise).rejects or expect(asyncFn()).rejects.
  2. If the value is sync, drop .rejects and assert directly.
  3. If you passed a function reference, call it: expect(fn()).rejects.

Example fix

// before
expect(fetchUser).rejects.toThrow();
// after
expect(fetchUser()).rejects.toThrow();
Defensive patterns

Strategy: type-guard

Validate before calling

const wrapper = typeof obj === 'function' ? obj() : obj;
if (typeof wrapper?.then !== 'function') throw new TypeError(`expect() target is ${typeof wrapper}, not a Promise — drop .rejects`);

Type guard

const isThenable = (v: unknown): v is PromiseLike<unknown> =>
  v != null && typeof (v as any).then === 'function';

Prevention

When it happens

Trigger: expect(42).rejects; expect('foo').rejects.toThrow(); expect(() => 5).rejects; expect(undefined).rejects. Triggered when typeof wrapper?.then !== 'function' at line 1158.

Common situations: Forgetting to call the function that returns a promise (expect(getPromise).rejects instead of expect(getPromise()).rejects), or asserting .rejects on a synchronous value.

Related errors


AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03). Data as JSON: /data/errors/c7cb813cfb25e20a.json. Report an issue: GitHub.