vitest-dev/vitest · error · TypeError
toContain() expected a DOM node as the argument, but got
Error message
toContain() expected a DOM node as the argument, but got ${typeof item} What it means
When the actual value is a DOM Node, toContain switches into DOM mode and requires the argument to also be a Node (it calls actual.contains(item)). Passing anything else (string, number, element-like object) throws a TypeError.
Solutions
- Pass an actual DOM Node: expect(parentNode).toContain(childNode).
- For text content, assert on the string: expect(node.textContent).toContain('hello').
- If the argument comes from another library, materialize it into a real Node first.
Example fix
// before
expect(container).toContain('Save')
// after
expect(container).toContain(saveButton) // a real DOM Node
// or assert on text
expect(container.textContent).toContain('Save') Defensive patterns
Strategy: type-guard
Validate before calling
function assertNodeForContain(actual, item) {
if (typeof Node !== 'undefined' && actual instanceof Node && !(item instanceof Node)) {
throw new TypeError('toContain() on a Node needs a Node argument; for text use node.textContent')
}
} Type guard
function isDomNode(v): v is Node {
return typeof Node !== 'undefined' && v instanceof Node
} Prevention
- When asserting DOM containment, pass a real Node as the expected item.
- For text checks, assert on node.textContent with toContain instead.
- Materialize library-wrapped elements into real Nodes before toContain.
When it happens
Trigger: expect(node).toContain(item) where actual instanceof Node is true but item is not a Node (e.g. a string of text or a number).
Common situations: Passing a text string expecting substring containment of textContent (use toContain on node.textContent or a text-based matcher); passing a cheerio/jsdom-lite wrapper that is not a real Node; passing an element from a different document.
Related errors
- .toMatch() expects to receive a string, but got
- You must provide an array or set to
- any() expects to be passed a constructor function. Please…
- Exact option does not support RegExp expected class names
- expect.customEqualityTesters: Must be set to an array of…
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/b7269c9df3668d2b.
Report an issue: GitHub.
Appendix: source
Thrown at packages/expect/src/jest-expect.ts:251
typeof expected === 'string'
? actual.includes(expected)
: actual.match(expected),
`expected #{this} to match #{exp}`,
`expected #{this} not to match #{exp}`,
expected,
actual,
)
})
def('toContain', function (item) {
const actual = this._obj as
| Iterable<unknown>
| string
| Node
| DOMTokenList
if (typeof Node !== 'undefined' && actual instanceof Node) {
if (!(item instanceof Node)) {
throw new TypeError(
`toContain() expected a DOM node as the argument, but got ${typeof item}`,
)
}
return this.assert(
actual.contains(item),
'expected #{this} to contain element #{exp}',
'expected #{this} not to contain element #{exp}',
item,
actual,
)
}
if (typeof DOMTokenList !== 'undefined' && actual instanceof DOMTokenList) {
assertTypes(item, 'class name', ['string'])
const isNot = utils.flag(this, 'negate') as boolean
const expectedClassList = isNot
? actual.value.replace(item, '').trim()View on GitHub (pinned to 1fa9837ec2)