vitest-dev/vitest · error · Error

Expected element or locator to be defined.

Error message

Expected element or locator to be defined.

What it means

Thrown by `serializeElement` at tester-utils.ts:294-296 when its first argument is falsy. The serializer is used by `toMatchScreenshot` (for masks) and other commands to convert an Element/Locator into a payload for the driver; a null/undefined input cannot be serialized.

Source

Thrown at packages/browser/src/client/tester/tester-utils.ts:295

    return String(re)
  }
  // Even number of backslashes followed by the quote -> insert a backslash.
  return String(re).replace(/(^|[^\\])(\\\\)*(["'`])/g, '$1$2\\$3').replace(/>>/g, '\\>\\>')
}

export function escapeForTextSelector(text: string | RegExp, exact: boolean): string {
  if (typeof text !== 'string') {
    return escapeRegexForSelector(text)
  }
  return `${JSON.stringify(text)}${exact ? 's' : 'i'}`
}

const provider = getBrowserState().provider
const kElementLocator = Symbol.for('$$vitest:locator-resolved')

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')

View on GitHub (pinned to d568f8ce37)

Solutions

  1. Resolve and verify the element before serializing: `const el = await locator.findElement(); if (!el) throw ...`.
  2. Filter undefined entries from mask arrays: `mask.filter(Boolean)` before passing to options.
  3. Use `page.locator(...).waitFor()` to guarantee presence before serializing.

Example fix

// before
await serializeElement(maybeMissingEl)

// after
if (!maybeMissingEl) throw new Error('mask element not found')
await serializeElement(maybeMissingEl)
Defensive patterns

Strategy: validation

Validate before calling

if (!elementOrLocator) throw new Error('element/locator is required')
await serializeElement(elementOrLocator)

Prevention

When it happens

Trigger: Calling `serializeElement(null)`, `serializeElement(undefined)`, or passing a value that resolves to undefined (e.g. `await locator.findElement()` when not found). Indirectly triggered when `toMatchScreenshot` options contain a `mask` entry that is null.

Common situations: Passing an optional element that wasn't resolved. Building a mask array where some entries are undefined. Race condition where an element was detached between resolution and serialization.

Related errors


AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03). Data as JSON: /data/errors/8ed4b34813adcb2f.json. Report an issue: GitHub.