{"record":{"id":"8ab4a1c6ad192380","repo":"vitest-dev/vitest","slug":"element-not-found-v-element","errorCode":null,"errorMessage":"Element not found: ${v.element}","messagePattern":"Element not found: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/browser-playwright/src/commands/select.ts","lineNumber":22,"sourceCode":"import type { UserEventCommand } from './utils'\nimport { getDescribedLocator } from './utils'\n\nexport const selectOptions: UserEventCommand<UserEvent['selectOptions']> = async (\n  context,\n  selector,\n  userValues,\n  options = {},\n) => {\n  const value = userValues as any as (string | { element: SerializedLocator })[]\n  const selectElement = getDescribedLocator(context, selector)\n\n  const values = await Promise.all(value.map(async (v) => {\n    if (typeof v === 'string') {\n      return v\n    }\n    const elementHandler = await getDescribedLocator(context, v.element).elementHandle()\n    if (!elementHandler) {\n      throw new Error(`Element not found: ${v.element}`)\n    }\n    return elementHandler\n  })) as (readonly string[]) | (readonly ElementHandle[])\n\n  await selectElement.selectOption(values, options)\n}\n","sourceCodeStart":4,"sourceCodeEnd":29,"githubUrl":"https://github.com/vitest-dev/vitest/blob/1fa9837ec26533512fdcad8baebf249771bd340a/packages/browser-playwright/src/commands/select.ts#L4-L29","documentation":"selectOptions accepts either string values or `{ element: SerializedLocator }` objects for `<option>` elements. For the object form the command resolves each locator to a Playwright ElementHandle; if the locator cannot be attached to a real DOM node (elementHandle() returns null), Vitest throws with the serialized locator text. This guards against silently selecting a detached/stale option.","triggerScenarios":"Calling `userEvent.selectOptions(select, [{ element: page.getByRole('option', { name: 'X' }) }])` when the option is not present, has been removed since the locator was created, is inside a shadow root the locator cannot reach, or the select has not yet rendered the options (timing).","commonSituations":"Selecting from a lazy-loaded option list before options render; option removed by virtualization after the locator was captured; selecting inside an iframe without scoping the locator; passing a locator built against the wrong frame.","solutions":["Ensure the `<option>` exists in the DOM at call time: `await expect(select).toBeVisible()` and wait for options first.","Prefer passing option values as plain strings (`selectOptions(select, ['apple'])`) when possible; the string path does not require resolving an ElementHandle.","If using locators, build them right before the call rather than capturing and reusing across async gaps.","Scope the option locator to the same frame/container as the select element."],"exampleFix":"// before\nconst opt = page.getByRole('option', { name: 'Apple' })\n// ... async work that removes the option ...\nawait userEvent.selectOptions(select, [{ element: opt }])\n\n// after\nawait userEvent.selectOptions(select, [{ element: page.getByRole('option', { name: 'Apple' }) }])\n// or, simplest:\nawait userEvent.selectOptions(select, ['apple'])","handlingStrategy":"validation","validationCode":"// ensure the option exists before passing it as { element }\nconst option = page.getByRole('option', { name: 'Apple' })\nawait expect(option).toBeVisible()\nawait userEvent.selectOptions(select, [{ element: option }])","typeGuard":"import type { SerializedLocator } from '@vitest/browser'\n\nfunction isOptionObject(v: unknown): v is { element: SerializedLocator } {\n  return typeof v === 'object' && v !== null && 'element' in v\n}","tryCatchPattern":"try {\n  await userEvent.selectOptions(select, [{ element: optionLocator }])\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith('Element not found')) {\n    // re-query the option or fall back to a value string\n    await userEvent.selectOptions(select, ['apple'])\n  } else {\n    throw err\n  }\n}","preventionTips":["Prefer option value strings over element locators for selectOptions.","Wait for options to render before selecting (toBeVisible / findByRole).","Build option locators immediately before use; do not reuse across async gaps."],"tags":["browser","dom","user-event","select","locator"],"backgroundTag":null,"analyzedSha":"1fa9837ec26533512fdcad8baebf249771bd340a","analyzedAt":"2026-08-11T16:11:39.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}