SeleniumHQ/selenium · error · NoSuchElementException

Cannot locate relative element with: {by.root}

Error message

Cannot locate relative element with: {by.root}

What it means

Raised by `find_element` when `by` is a `RelativeBy` (the Friendly / relative locator API) and the underlying `find_elements` returns an empty list — meaning no element matched the relative locator graph. It then raises NoSuchElementException with the root descriptor. This is a 'nothing matched' result, not a malformed locator.

Source

Thrown at py/selenium/webdriver/remote/webdriver.py:907

        Args:
            by: The locating strategy to use. Default is `By.ID`. Supported
                values include: By.ID, By.NAME, By.XPATH, By.CSS_SELECTOR,
                By.CLASS_NAME, By.TAG_NAME, By.LINK_TEXT, By.PARTIAL_LINK_TEXT,
                or RelativeBy.
            value: The locator value to use with the specified `by` strategy.

        Returns:
            The first matching WebElement found on the page.

        Example:
            `element = driver.find_element(By.ID, 'foo')`
        """
        by, value = self.locator_converter.convert(by, value)

        if isinstance(by, RelativeBy):
            elements = self.find_elements(by=by, value=value)
            if not elements:
                raise NoSuchElementException(f"Cannot locate relative element with: {by.root}")
            return elements[0]

        return self.execute(Command.FIND_ELEMENT, {"using": by, "value": value})["value"]

    def find_elements(self, by: str | By | RelativeBy = By.ID, value: str | None = None) -> list[WebElement]:
        """Find elements given a By strategy and locator.

        Args:
            by: The locating strategy to use. Default is `By.ID`. Supported
                values include: By.ID, By.NAME, By.XPATH, By.CSS_SELECTOR,
                By.CLASS_NAME, By.TAG_NAME, By.LINK_TEXT, By.PARTIAL_LINK_TEXT,
                or RelativeBy.
            value: The locator value to use with the specified `by` strategy.

        Returns:
            List of WebElements matching locator strategy found on the page.

        Example:

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Wait for the target to be present, then retry the relative find.
  2. Loosen the relative filters (drop a to_left_of/near constraint) to widen the match.
  3. Switch to find_elements to handle the zero-match case gracefully, or use a direct locator as fallback.

Example fix

# before
btn = driver.find_element(with_tag('button').to_right_of(anchor))

# after
from selenium.webdriver.support.ui import WebDriverWait
btns = WebDriverWait(driver, 10).until(
    lambda d: d.find_elements(with_tag('button').to_right_of(anchor)))
btn = btns[0]
Defensive patterns

Strategy: try-catch

Validate before calling

matches = driver.find_elements(by)  # RelativeBY -> [] if none
if not matches:
    raise NoSuchElementException('no relative match; wait or loosen filters')

Try / catch

from selenium.common.exceptions import NoSuchElementException
try:
    el = driver.find_element(rel_by)
except NoSuchElementException:
    # target not present yet; wait + retry, or fall back to a direct locator

Prevention

When it happens

Trigger: Calling driver.find_element(with_tag('button').to_right_of(el)) when no button exists to the right of the anchor; the anchor element is stale/hidden; the page hasn't rendered the target yet; filters (near/to_left_of) over-constrain.

Common situations: Relative locators on dynamic/async UI before targets render; anchors that scrolled out of view; overly strict multi-filter combos that exclude everything; responsive layouts where geometry differs.

Related errors


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