vitest-dev/vitest · error · Error

Received value must be an object when the matcher has…

Error message

Received value must be an object when the matcher has properties

What it means

In SnapshotClient.match, when the properties option is an object (used to filter/compare a subset of received), received must also be an object. If received is null, undefined, or a primitive, the comparison cannot proceed and the error is thrown after marking the expected snapshot as checked.

Example fix

// before
expect(getCount()).toMatchSnapshot({ value: expect.any(Number) })
// after
expect({ value: getCount() }).toMatchSnapshot({ value: expect.any(Number) })
Defensive patterns

Strategy: type-guard

Validate before calling

if (properties != null && (typeof received !== 'object' || received === null)) {
  throw new Error('properties matcher requires received to be a non-null object')
}
client.match({ filepath, name, received, properties })

Type guard

function canUseProperties(received: unknown, properties: unknown): boolean { return properties == null || (typeof received === 'object' && received !== null) }

Prevention

When it happens

Trigger: Calling toMatchSnapshot with a properties argument (second matcher arg) on a primitive received value, e.g. expect(5).toMatchSnapshot({ a: 1 }) or expect(null).toMatchSnapshot({}); also when received is undefined.

Common situations: Passing an expected-shape object as properties to a snapshot of a primitive; mismatch between the matcher's properties argument and the actual value type; refactoring that changed received from object to primitive without updating the assertion.

Related errors


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

Appendix: source

Thrown at packages/snapshot/src/client.ts:151

    if (!filepath) {
      throw new Error('Snapshot cannot be used outside of test')
    }

    const snapshotState = this.getSnapshotState(filepath)
    const testName = [name, ...(message ? [message] : [])].join(' > ')

    // Probe first so we can mark as checked even on early return
    const expectedSnapshot = snapshotState.probeExpectedSnapshot({
      testName,
      testId,
      isInline,
      inlineSnapshot,
    })

    if (typeof properties === 'object') {
      if (typeof received !== 'object' || !received) {
        expectedSnapshot.markAsChecked()
        throw new Error(
          'Received value must be an object when the matcher has properties',
        )
      }

      let propertiesPass: boolean
      try {
        propertiesPass = this.options.isEqual?.(received, properties) ?? false
      }
      catch (err) {
        expectedSnapshot.markAsChecked()
        throw err
      }
      if (!propertiesPass) {
        expectedSnapshot.markAsChecked()
        return {
          pass: false,
          message: () => errorMessage || 'Snapshot properties mismatched',
          actual: received,

View on GitHub (pinned to 1fa9837ec2)