vitest-dev/vitest · error · TypeError

You must provide an object to

Error message

You must provide an object to ${this.toString()}, not '${typeof this.sample}'.

What it means

ObjectContaining's asymmetricMatch throws a TypeError if this.sample is not an object. This is a match-time guard (inside asymmetricMatch), so the error fires when the matcher is actually evaluated against a value, not when expect.objectContaining is constructed.

Solutions

  1. Pass an object literal describing the required subset: expect.objectContaining({ id: 1 }).
  2. If you only need a single primitive property, wrap it: expect.objectContaining({ status: 'active' }).
  3. Validate the shape before constructing the matcher in dynamic scenarios.

Example fix

// before
expect(res).toEqual(expect.objectContaining('id'))
// after
expect(res).toEqual(expect.objectContaining({ id: 1, active: true }))
Defensive patterns

Strategy: type-guard

Validate before calling

function asObjectContaining(sample) {
  if (sample === null || typeof sample !== 'object') {
    throw new TypeError('expect.objectContaining needs a plain object')
  }
  return expect.objectContaining(sample)
}

Type guard

function isPlainObject(v): v is Record<string, unknown> {
  return v !== null && typeof v === 'object' && !Array.isArray(v)
}

Prevention

When it happens

Trigger: expect.objectContaining(sample) built with a non-object sample (string/number/null), then used in an assertion like toEqual(expect.objectContaining(...)).

Common situations: Passing a primitive to objectContaining; a default parameter that resolved to undefined; constructing the matcher from untyped config data.

Related errors


AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11). Data as JSON: /api/errors/971ba9e92d950478. Report an issue: GitHub.

Appendix: source

Thrown at packages/expect/src/jest-asymmetric-matchers.ts:154

    if (Object.hasOwn(obj, property)) {
      return true
    }

    return this.hasProperty(this.getPrototype(obj), property)
  }

  getProperties(obj: object): (string | symbol)[] {
    return [
      ...Object.keys(obj),
      ...Object.getOwnPropertySymbols(obj).filter(
        s => Object.getOwnPropertyDescriptor(obj, s)?.enumerable,
      ),
    ]
  }

  asymmetricMatch(other: any, customTesters?: Array<Tester>): boolean {
    if (typeof this.sample !== 'object') {
      throw new TypeError(
        `You must provide an object to ${this.toString()}, not '${typeof this
          .sample}'.`,
      )
    }

    let result = true

    const properties = this.getProperties(this.sample)
    for (const property of properties) {
      if (
        !this.hasProperty(other, property)
      ) {
        result = false
        break
      }
      const value = this.sample[property]
      const otherValue = other[property]
      if (!equals(

View on GitHub (pinned to 1fa9837ec2)