Skip to content
SDETRole
SDETRole

Selenium interview question

How do you handle StaleElementReferenceException in Selenium?

intermediate 2–5 yrs #exceptions#waits#page-object-model

Short answer

It means the element reference points to a node that was removed or re-rendered. Re-locate the element after the DOM changes instead of caching WebElements, wait for the new state with WebDriverWait, and use Page Objects that find elements lazily.

Answer

StaleElementReferenceException is thrown when you use a WebElement whose underlying DOM node is no longer attached to the document. A WebElement is a handle to one specific node, not a description of how to find it. If the framework (React, Angular, Vue) replaces that node, the handle is dead even if an identical-looking element now sits in the same place.

Typical causes

  • The page navigated or reloaded after you found the element.
  • A framework re-rendered a list or form after an API response (sorting a table, applying a filter, validation messages appearing).
  • You stored elements in a field or a list, then performed an action that rebuilt part of the page.
  • PageFactory proxies were cached with @CacheLookup.
List<WebElement> rows = driver.findElements(By.cssSelector("tr.order"));
driver.findElement(By.id("sort-by-date")).click();   // table re-renders
rows.get(0).getText();                               // StaleElementReferenceException

Fixes, in order of preference

1. Store locators, not elements

Keep By objects and look elements up at the moment you use them. Page Objects should expose methods that find on demand:

public class OrdersPage {
    private final WebDriver driver;
    private final WebDriverWait wait;
    private static final By ROWS = By.cssSelector("tr.order");
    private static final By SORT_BY_DATE = By.id("sort-by-date");

    public OrdersPage(WebDriver driver) {
        this.driver = driver;
        this.wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    public String firstOrderId() {
        return driver.findElements(ROWS).get(0).getAttribute("data-id");
    }
}

2. Wait for the change to complete

The real bug is usually that the test acted before the re-render finished. Wait for the old element to go stale, or for the new state to appear, then re-locate:

WebElement oldFirstRow = driver.findElement(ROWS);
driver.findElement(SORT_BY_DATE).click();
wait.until(ExpectedConditions.stalenessOf(oldFirstRow));
wait.until(ExpectedConditions.visibilityOfElementLocated(ROWS));
String first = driver.findElements(ROWS).get(0).getText();

ExpectedConditions.refreshed(condition) is another option: it wraps a condition and treats a stale reference as “not yet”, so the wait re-evaluates.

3. A bounded retry for genuinely racy UI

Some widgets re-render unpredictably (live dashboards, polling lists). A FluentWait that ignores the exception and re-finds the element inside the lambda is acceptable:

new WebDriverWait(driver, Duration.ofSeconds(5))
    .ignoring(StaleElementReferenceException.class)
    .until(d -> { d.findElement(By.id("refresh")).click(); return true; });

Keep it local to that interaction. Wrapping every click in a global retry hides real defects such as a component re-rendering in a loop.

What interviewers look for

  • You explain the cause precisely: the reference, not the locator, is stale.
  • Your default fix is architectural (lazy lookup, waiting for the right state), not try/catch.
  • You treat retries as a targeted tool and know when they mask bugs.

Common mistakes

  • Confusing it with NoSuchElementException (that means the locator matched nothing).
  • Adding Thread.sleep before the action.
  • Catching the exception and silently continuing.

A strong answer covers

  • Explains cause: DOM node detached or re-rendered
  • Re-locate the element rather than caching it
  • Use explicit waits for the new state
  • Retry is a bounded last resort, not a blanket fix
Practise answering under time pressure

Type to search across SDETRole.

Full-text search by Pagefind · runs in your browser Open search page →