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

  1. Inspect actual text: const texts = await Promise.all((await sel.getOptions()).map(o => o.getText())); then pick.
  2. Match exactly including case, or normalize: pick the option whose text startsWith the wanted prefix and click it.
  3. If only a substring is known, find the option by XPath: By.xpath(`.//option[contains(normalize-space(.), '${frag}')]`) and click it.
  4. 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

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


AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14). Data as JSON: /api/errors/7f6aa7675cb15b59. Report an issue: GitHub.