vitest-dev/vitest · error · TypeError
Async schema validation is not supported in asymmetric match
Error message
Async schema validation is not supported in asymmetric matchers.
What it means
Thrown as a TypeError inside SchemaMatching.asymmetricMatch when the schema's validate() returns a Promise. Asymmetric matchers run synchronously within the equality check, so an async schema cannot be evaluated; Vitest refuses to silently return a wrong result.
Source
Thrown at packages/expect/src/jest-asymmetric-matchers.ts:416
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
}
toString() {
return `Schema${this.inverse ? 'Not' : ''}Matching`
}
getExpectedType() {
return 'object'
}
toAsymmetricMatcher(): string {
const { utils } = this.getMatcherContext()View on GitHub (pinned to d568f8ce37)
Solutions
- Use a synchronous schema variant for asymmetric matching (remove async refinements).
- Validate explicitly with await schema['~standard'].validate(value) and assert on the result instead of using schemaMatching.
- Refactor the async logic out of the schema used for matching.
Example fix
// before
const schema = z.object({ email: z.string().email().refine(async () => checkDb()) })
expect(body).toEqual(expect.schemaMatching(schema)) // throws: async validate
// after
const result = await schema['~standard'].validate(body)
expect(result.issues ?? []).toEqual([]) Defensive patterns
Strategy: validation
Validate before calling
// detect async validation before using schemaMatching
function isSyncSchema(schema: any): boolean {
const probe = {}
const result = schema['~standard'].validate(probe)
return !(result instanceof Promise)
}
if (!isSyncSchema(schema)) {
throw new TypeError('Use a sync schema for schemaMatching, or await validate() manually')
} Type guard
function isSyncValidator(schema: any): boolean {
// best-effort: probe with a sentinel once and cache
const r = schema['~standard'].validate(undefined)
return !(r instanceof Promise)
} Try / catch
try {
expect(value).toEqual(expect.schemaMatching(schema))
} catch (e) {
if (/Async schema validation/i.test(String((e as Error).message))) {
const result = await schema['~standard'].validate(value)
expect(result.issues ?? []).toEqual([])
} else throw e
} Prevention
- Avoid async refinements (refine/superRefine) in schemas used for asymmetric matching.
- If async is required, validate with await and assert on the result instead.
- Probe schemas once at module load to confirm validate() is synchronous.
When it happens
Trigger: Using expect.schemaMatching(schema) where schema['~standard'].validate(value) returns a Promise (the validator does I/O, async refinements, or DB lookups). The match throws at comparison time, not construction.
Common situations: A zod/valibot schema with async refine/superRefine or async piped validators; a custom Standard Schema whose validate is async; moving a schema that worked in expect() into an asymmetric context.
Related errors
- SchemaMatching expected to receive a Standard Schema.
- Expected is not a string
- You must provide an object to ${this.toString()}, not '${typ
- You must provide an array to ${this.toString()}, not '${type
- any() expects to be passed a constructor function. Please pa
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/dc2501d4c85193fa.json.
Report an issue: GitHub.