vitest-dev/vitest · error · TypeError
Async schema validation is not supported in asymmetric…
Error message
Async schema validation is not supported in asymmetric matchers.
What it means
SchemaMatching's asymmetricMatch calls sample['~standard'].validate(other) and throws a TypeError if the result is a Promise. Asymmetric matchers are synchronous, so async schema validation (refinements, transforms that await) cannot be evaluated inline.
Solutions
- Remove async refinements/transforms from the schema used in schemaMatching, or use a separate sync schema for the assertion.
- Validate explicitly with await schema['~standard'].validate(value) inside an async test and assert on the issues array.
- Use expect(await result).toEqual(...) patterns with a pre-validated value instead of the asymmetric matcher.
Example fix
// before: schema has an async refinement
const schema = z.object({ email: z.string().email().refine(async (v) => await isUnique(v)) })
expect(payload).toEqual(expect.schemaMatching(schema))
// after: validate explicitly in an async test
const result = await schema['~standard'].validate(payload)
expect(result.issues ?? []).toEqual([]) Defensive patterns
Strategy: validation
Validate before calling
// Detect async validation up front and switch strategies.
async function validateSyncOrThrow(schema, value) {
const result = schema['~standard'].validate(value)
if (result instanceof Promise) {
throw new TypeError('Schema uses async validation; await it in the test instead.')
}
return result
} Type guard
function isSyncSchemaResult(result): boolean {
return !(result instanceof Promise)
} Try / catch
try {
expect(payload).toEqual(expect.schemaMatching(schema))
} catch (e) {
if (/Async schema validation is not supported/.test(String(e?.message))) {
const r = await schema['~standard'].validate(payload)
expect(r.issues ?? []).toEqual([])
return
}
throw e
} Prevention
- Keep schemas used in expect.schemaMatching synchronous (no async refinements/transforms).
- Validate explicitly with await in async tests when async validation is required.
- Unit-check that schema['~standard'].validate returns synchronously before using the matcher.
When it happens
Trigger: Using expect.schemaMatching(schema) in a synchronous expect(...).toEqual(...) where the schema contains async refinements or async transforms, so validate() returns a Promise.
Common situations: Zod schemas with .refine(async ...), valibot schemas with async actions, or any schema whose validation pipeline is async; using schemaMatching inside toEqual instead of an async-aware assertion.
Related errors
- SchemaMatching expected to receive a Standard Schema.
- any() expects to be passed a constructor function. Please…
- Asymmetric matcher does not implement toAsymmetricMatcher()
- Expected is not a Number
- Expected is not a string
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/dc2501d4c85193fa.
Report an issue: GitHub.
Appendix: 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 1fa9837ec2)