SeleniumHQ/selenium · error · Error
Cannot locate option with text: ${text}
Error message
Cannot locate option with text: ${text} What it means
Thrown by selectByVisibleText() when no <option> whose trimmed text exactly equals the (trimmed) argument was found. Matching uses normalize-space(.) comparison, so leading/trailing whitespace is ignored but the full visible text must match exactly (case-sensitive, no partial).
Source
Thrown at javascript/selenium-webdriver/lib/select.js:301
candidates = await this.element.findElements(By.xpath(xpath))
}
const trimmed = text.trim()
for (let option of candidates) {
const optionText = await option.getText()
if (trimmed === optionText.trim()) {
await this.setSelected(option)
if (!(await this.isMultiple())) {
return
}
matched = true
}
}
}
if (!matched) {
throw new Error(`Cannot locate option with text: ${text}`)
}
}
/**
* Returns a list of all options belonging to this select tag
* @returns {!Promise<!Array<!WebElement>>}
*/
async getOptions() {
return await this.element.findElements({ tagName: 'option' })
}
/**
* Returns a boolean value if the select tag is multiple
* @returns {Promise<boolean>}
*/
async isMultiple() {
return this.multiple
}View on GitHub (pinned to aa36b38e69)
Solutions
- Inspect actual text: const texts = await Promise.all((await sel.getOptions()).map(o => o.getText())); then pick.
- Match exactly including case, or normalize: pick the option whose text startsWith the wanted prefix and click it.
- If only a substring is known, find the option by XPath: By.xpath(`.//option[contains(normalize-space(.), '${frag}')]`) and click it.
- Trim and compare unicode-normalized strings.
Example fix
// before
await sel.selectByVisibleText('United'); // actual text is 'United States'
// after
const opts = await sel.getOptions();
for (const o of opts) {
if ((await o.getText()).startsWith('United')) { await o.click(); break; }
} Defensive patterns
Strategy: validation
Validate before calling
async function findOptionByText(sel, text) {
const t = String(text).trim();
for (const o of await sel.getOptions()) {
if ((await o.getText()).trim() === t) return o;
}
return null;
} Type guard
async function hasOptionWithText(sel, text) {
return Boolean(await findOptionByText(sel, text));
} Try / catch
try {
await sel.selectByVisibleText(t);
} catch (e) {
if (/Cannot locate option with text/.test(e.message)) {
const opts = await sel.getOptions();
const match = opts.find(async o => (await o.getText()).includes(t));
if (match) await match.click(); else throw e;
} else throw e;
} Prevention
- Match is exact + case-sensitive + trimmed; verify the real option text.
- For partial matches use a contains() XPath manually.
- Normalize unicode/case in fixtures for localized pages.
When it happens
Trigger: selectByVisibleText('United States') when the option text is 'United States of America' (partial doesn't match); case mismatch ('united states'); text differs by locale or non-breaking spaces; option text includes extra words.
Common situations: i18n/localized pages; options with parenthetical suffixes ('Option A (default)'); copy-pasted text with smart quotes; partial-match assumptions.
Related errors
- Cannot locate option with value: ${value}
- Invalid locator
- input must be a string
- Element must not be null. Please provide a valid <select> el
- Select only works on <select> elements
AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14).
Data as JSON: /api/errors/7f6aa7675cb15b59.
Report an issue: GitHub.