vitest-dev/vitest · error · TypeError
You must provide an object to ${this.toString()}, not '${typ
Error message
You must provide an object to ${this.toString()}, not '${typeof this.sample}'. What it means
Thrown as a TypeError inside ObjectContaining.asymmetricMatch when this.sample is not an object. ObjectContaining checks that the received value has (and equals) a set of expected properties, so the expected sample must be a property bag.
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 d568f8ce37)
Solutions
- Pass an object literal of expected properties: expect.objectContaining({ id: 1 }).
- If you only need key presence, wrap the key: expect.objectContaining({ key: expect.anything() }).
- Validate the variable is an object before using it as the sample.
Example fix
// before
expect(res).toEqual(expect.objectContaining('id'))
// after
expect(res).toEqual(expect.objectContaining({ id: expect.any(Number) })) Defensive patterns
Strategy: type-guard
Validate before calling
function asRecord(v: unknown): Record<string, unknown> {
if (typeof v !== 'object' || v === null || Array.isArray(v)) {
throw new TypeError(`objectContaining needs an object, got ${typeof v}`)
}
return v as Record<string, unknown>
}
expect(res).toEqual(expect.objectContaining(asRecord(shape))) Type guard
function isPlainObject(v: unknown): v is Record<string, unknown> {
return typeof v === 'object' && v !== null && !Array.isArray(v)
} Prevention
- Always pass object literals ({...}) to objectContaining.
- Reject null/arrays at the type level when building dynamic expected shapes.
- Wrap single key checks as { key: expect.anything() }.
When it happens
Trigger: Constructing expect.objectContaining(value) where value is a primitive (string, number, null, undefined) — the constructor accepts it but matching throws because typeof this.sample !== 'object'.
Common situations: Passing a single key name instead of an object; passing null/undefined; a variable that was expected to be an object but is actually a primitive after a refactor.
Related errors
- Expected is not a string
- You must provide an array to ${this.toString()}, not '${type
- any() expects to be passed a constructor function. Please pa
- Expected is not a String or a RegExp
- Expected is not a Number
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/971ba9e92d950478.json.
Report an issue: GitHub.