vitest-dev/vitest · error · TypeError

SchemaMatching expected to receive a Standard Schema.

Error message

SchemaMatching expected to receive a Standard Schema.

What it means

SchemaMatching (expect.schemaMatching) requires a Standard Schema object — one exposing the '~standard' descriptor with a validate function. isStandardSchema(sample) returns false for plain objects, classes, or zod/valibot versions that predate Standard Schema support.

Solutions

  1. Use a schema library that implements Standard Schema (zod v4+, valibot, arktype) and pass the schema object directly.
  2. Upgrade the schema library to a version that ships Standard Schema support.
  3. If stuck on zod v3/Yup/Joi, write a custom matcher or upgrade rather than passing the raw schema.

Example fix

// before (zod v3 — not a Standard Schema)
import { z } from 'zod' // v3
expect(payload).toEqual(expect.schemaMatching(z.object({ id: z.number() })))
// after (zod v4 — Standard Schema compliant)
import { z } from 'zod' // v4
expect(payload).toEqual(expect.schemaMatching(z.object({ id: z.number() })))
Defensive patterns

Strategy: type-guard

Validate before calling

function isStandardSchema(v): boolean {
  return v != null && typeof v === 'object' && '~standard' in v && typeof v['~standard']?.validate === 'function'
}
function asSchemaMatching(schema) {
  if (!isStandardSchema(schema)) {
    throw new TypeError('Pass a Standard Schema (zod v4 / valibot / arktype)')
  }
  return expect.schemaMatching(schema)
}

Type guard

function isStandardSchema(v): v is { '~standard': { validate: (v: unknown) => unknown } } {
  return v != null && typeof v === 'object' && '~standard' in v && typeof (v as any)['~standard']?.validate === 'function'
}

Prevention

When it happens

Trigger: expect.schemaMatching(sample) where sample lacks the '~standard' key (e.g. a raw z.object call on zod v3, a plain validation function, or a class instance).

Common situations: Using zod v3 (no Standard Schema) — Standard Schema landed in zod v4 / valibot v0.31+ / arktype; passing a Yup or Joi schema (no Standard Schema adapter); wrapping the schema in an extra layer.

Related errors


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

Appendix: source

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

  override getExpectedType() {
    return 'number'
  }

  override toAsymmetricMatcher(): string {
    return [
      this.toString(),
      this.sample,
      `(${pluralize('digit', this.precision)})`,
    ].join(' ')
  }
}

export class SchemaMatching extends AsymmetricMatcher<StandardSchemaV1<unknown, unknown>> {
  private result: StandardSchemaV1.Result<unknown> | undefined

  constructor(sample: StandardSchemaV1<unknown, unknown>, inverse = false) {
    if (!isStandardSchema(sample)) {
      throw new TypeError(
        'SchemaMatching expected to receive a Standard Schema.',
      )
    }
    super(sample, inverse)
  }

  asymmetricMatch(other: unknown): boolean {
    const result = this.sample['~standard'].validate(other)

    // Check if the result is a Promise (async validation)
    if (result instanceof Promise) {
      throw new TypeError('Async schema validation is not supported in asymmetric matchers.')
    }

    this.result = result
    const pass = !this.result.issues || this.result.issues.length === 0

    return this.inverse ? !pass : pass

View on GitHub (pinned to 1fa9837ec2)