vitest-dev/vitest · error · Error
Expected element or locator to be an instance of Element or…
Error message
Expected element or locator to be an instance of Element or Locator.
What it means
Thrown by `serializeElement` as its final fallthrough after the input is confirmed truthy, is not an `instanceof Element`, and is not a `Locator` (detected via the `$$vitest:locator` symbol). The function only knows how to serialize actual DOM elements and Locator objects; any other truthy value (a plain object, a number, a string, a Window, a Document) reaches this branch and is rejected.
Solutions
- Pass only a DOM `Element` or a real Vitest `Locator` instance.
- If using a custom Locator-like object, ensure it carries `Symbol.for('$$vitest:locator')` and a compatible shape — or, better, use the official Locator API.
- Guard the call site: `if (el instanceof Element || isLocator(el)) { ... }`.
Example fix
// before await serializeElement(document) // Document is not an Element // after await serializeElement(document.documentElement)
Defensive patterns
Strategy: type-guard
Validate before calling
import { isLocator } from 'vitest/browser' // or local equivalent
function isSerializableTarget(v: unknown): v is Element | Locator {
return v instanceof Element || (!!v && typeof v === 'object' && Symbol.for('$$vitest:locator') in (v as object))
}
if (!isSerializableTarget(target)) throw new TypeError('pass an Element or Locator')
await serializeElement(target) Type guard
function isSerializableTarget(v: unknown): v is Element | Locator {
return v instanceof Element
|| (!!v && typeof v === 'object' && Symbol.for('$$vitest:locator') in (v as object))
} Prevention
- Pass only DOM Elements or real Vitest Locators.
- Avoid custom Locator-like objects missing the internal symbol.
- Guard call sites with the type guard before forwarding.
When it happens
Trigger: Passing a Window, Document, NodeList entry that is a text node, a plain object mimicking a Locator but missing the symbol, or any non-Element/non-Locator value to `serializeElement`.
Common situations: Forwarding a value that the caller assumed was an element/Locator; a fake/mock Locator missing the internal symbol; cross-realm objects whose `instanceof Element` check fails.
Related errors
- Expected DOM element to be an instance of Element, received
- Expected element or locator to be defined.
- Element not found
- Invalid element or locator
- received value must an HTMLElement or an SVGElement or a…
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/b15ccffa540eac02.
Report an issue: GitHub.
Appendix: source
Thrown at packages/browser/src/client/tester/tester-utils.ts:310
export async function serializeElement(elementOrLocator: Element | Locator, options?: SelectorOptions): Promise<SerializedLocator> {
if (!elementOrLocator) {
throw new Error('Expected element or locator to be defined.')
}
if (elementOrLocator instanceof Element) {
const selector = convertElementToCssSelector(elementOrLocator)
return { selector, locator: __INTERNAL._asLocator('javascript', selector) }
}
if (isLocator(elementOrLocator)) {
if (provider === 'playwright' || kElementLocator in elementOrLocator) {
return elementOrLocator.serialize()
}
const element = await elementOrLocator.findElement(options)
const selector = convertElementToCssSelector(element)
const locator = __INTERNAL._asLocator('javascript', selector)
return { selector, locator }
}
throw new Error('Expected element or locator to be an instance of Element or Locator.')
}
const kLocator = Symbol.for('$$vitest:locator')
export function isLocator(element: unknown): element is Locator {
return (!!element && typeof element === 'object' && kLocator in element)
}
const DEFAULT_WHEEL_DELTA = 100
export function resolveUserEventWheelOptions(options: UserEventWheelOptions): UserEventWheelDeltaOptions {
let delta: UserEventWheelDeltaOptions['delta']
if (options.delta) {
delta = options.delta
}
else {
switch (options.direction) {View on GitHub (pinned to 1fa9837ec2)