SeleniumHQ/selenium · error · UnexpectedTagNameException

Select only works on <select> elements, not on {webelement.t

Error message

Select only works on <select> elements, not on {webelement.tag_name}

What it means

The `Select` helper only wraps genuine `<select>` elements. Its constructor checks `webelement.tag_name.lower() != 'select'` and raises `UnexpectedTagNameException` otherwise, because option-list semantics (multiple, options, select/deselect) only apply to select tags.

Source

Thrown at py/selenium/webdriver/support/select.py:39

from selenium.webdriver.remote.webelement import WebElement


class Select:
    def __init__(self, webelement: WebElement) -> None:
        """Constructor. A check is made that the given element is a SELECT tag.

        Args:
            webelement: SELECT element to wrap

        Example:
            from selenium.webdriver.support.ui import Select
            Select(driver.find_element(By.TAG_NAME, "select")).select_by_index(2)

        Raises:
            UnexpectedTagNameException: If the element is not a SELECT tag
        """
        if webelement.tag_name.lower() != "select":
            raise UnexpectedTagNameException(f"Select only works on <select> elements, not on {webelement.tag_name}")
        self._el = webelement
        multi = self._el.get_dom_attribute("multiple")
        self.is_multiple = multi and multi != "false"

    @property
    def options(self) -> list[WebElement]:
        """Returns a list of all options belonging to this select tag."""
        return self._el.find_elements(By.TAG_NAME, "option")

    @property
    def all_selected_options(self) -> list[WebElement]:
        """Return a list of all selected options belonging to this select tag."""
        return [opt for opt in self.options if opt.is_selected()]

    @property
    def first_selected_option(self) -> WebElement:
        """Return the first selected option or the currently selected option."""
        for opt in self.options:

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Verify the element's tag is 'select' before constructing Select
  2. Refine the locator to target the actual `<select>` element, e.g. `driver.find_element(By.TAG_NAME, 'select')`
  3. If the dropdown is a custom widget, do not use Select — interact via click/keys directly
  4. Inspect with `el.tag_name` to confirm which element was actually located

Example fix

// before
el = driver.find_element(By.CSS_SELECTOR, ".dropdown")
select = Select(el)

// after
el = driver.find_element(By.CSS_SELECTOR, "select#country")
select = Select(el)
Defensive patterns

Strategy: type-guard

Validate before calling

el = driver.find_element(By.CSS_SELECTOR, "select#country")
if el.tag_name.lower() != "select":
    raise ValueError(f"expected <select>, got <{el.tag_name}>")
select = Select(el)

Type guard

def is_select_element(el) -> bool:
    return getattr(el, "tag_name", "").lower() == "select"

Try / catch

from selenium.common.exceptions import UnexpectedTagNameException

try:
    select = Select(el)
except UnexpectedTagNameException:
    # custom dropdown — interact directly
    el.click()

Prevention

When it happens

Trigger: Constructing `Select(el)` where `el` is a `<div>`, `<ul>`, or any non-select element — common with custom dropdown widgets built from divs. Also when the located element is a wrapper container rather than the actual select, or when the page changed and the locator now matches a different tag.

Common situations: Modern single-page apps use custom (div/ul-based) dropdowns that are not real `<select>` elements; the test grabbed a parent container; a locator matched a different element after a UI redesign; trying to use Select on a Shadow DOM custom component.

Related errors


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