vitest-dev/vitest · error · Error
Element not found: ${v.element}
Error message
Element not found: ${v.element} What it means
Thrown by the Playwright selectOptions user-event command when one of the provided values is a SerializedLocator whose underlying DOM element cannot be resolved to an ElementHandle (elementHandle() returned null). This means the selector matched nothing in the iframe at select time.
Source
Thrown at packages/browser-playwright/src/commands/select.ts:22
import type { UserEventCommand } from './utils'
import { getDescribedLocator } from './utils'
export const selectOptions: UserEventCommand<UserEvent['selectOptions']> = async (
context,
selector,
userValues,
options = {},
) => {
const value = userValues as any as (string | { element: SerializedLocator })[]
const selectElement = getDescribedLocator(context, selector)
const values = await Promise.all(value.map(async (v) => {
if (typeof v === 'string') {
return v
}
const elementHandler = await getDescribedLocator(context, v.element).elementHandle()
if (!elementHandler) {
throw new Error(`Element not found: ${v.element}`)
}
return elementHandler
})) as (readonly string[]) | (readonly ElementHandle[])
await selectElement.selectOption(values, options)
}
View on GitHub (pinned to d568f8ce37)
Solutions
- Wait for the option to be attached before selecting: await page.element(locator).waitFor().
- Verify the <option> exists with an expect(locator).toBeVisible() assertion first.
- Prefer passing option values as plain strings (the value attribute) instead of element locators, which avoids the handle lookup.
- Re-query the locator immediately before the select to avoid staleness.
Example fix
// before
await page.selectOptions(selectEl, [{ element: optionLocator }]) // option not in DOM
// after
await page.element(optionLocator).waitFor({ state: 'attached' })
await page.selectOptions(selectEl, [{ element: optionLocator }])
// or simpler: pass value strings
await page.selectOptions(selectEl, ['option-value-1']) Defensive patterns
Strategy: validation
Validate before calling
const handle = await page.element(locator).elementHandle()
if (!handle) throw new Error('option not attached; cannot select')
await page.selectOptions(selectEl, [{ element: locator }]) Type guard
async function optionAttached(locator: SerializedLocator): Promise<boolean> {
const h = await page.element(locator).elementHandle()
return h !== null
} Try / catch
try {
await page.selectOptions(selectEl, [{ element: loc }])
} catch (err) {
if (err instanceof Error && /Element not found/.test(err.message)) {
await page.element(loc).waitFor({ state: 'attached' })
await page.selectOptions(selectEl, [{ element: loc }])
} else throw err
} Prevention
- Wait for the <option> to be attached before selecting.
- Prefer value-string options over element locators to avoid handle lookups.
- Re-query locators immediately before use to avoid staleness after re-renders.
When it happens
Trigger: Calling page.selectOptions(select, [{ element: locator }]) where locator points to an <option> that is not present, not yet rendered, or lives in a different frame. Also when passing a stale locator captured before a re-render.
Common situations: Selecting options in async-loaded dropdowns, shadow-DOM selects, selects re-rendered after a state change, or racing the select before the list is populated.
Related errors
- Cannot upload files outside of a test
- Cannot take a screenshot without a test path
- The ${provider.name} provider does not support tracing.
- stopChunkTrace cannot be called outside of the test file.
- The ${context.provider.name} provider does not support traci
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/8ab4a1c6ad192380.json.
Report an issue: GitHub.