Glossary · UI automation
StaleElementReferenceException
Also called: stale element, stale element reference, stale element exception
Definition
A Selenium error thrown when a test uses a WebElement whose DOM node was removed or replaced after it was found, typically after a re-render.
StaleElementReferenceException means the element your code is holding no longer exists in the page. A WebElement in Selenium is a reference to one specific DOM node. If the application removes that node, for example because a framework re-rendered the list, the page navigated, or an AJAX update replaced a section, the reference points at nothing and any call on it throws this exception.
Example
WebElement firstRow = driver.findElement(By.cssSelector("table tbody tr"));
driver.findElement(By.id("sort-by-date")).click(); // table body is re-rendered
firstRow.getText(); // StaleElementReferenceException
The element looks identical on screen, but it is a new node. The old reference is dead.
How to fix it
Find the element again at the moment you need it, and wait for the new state rather than catching the exception.
By firstRow = By.cssSelector("table tbody tr");
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement before = driver.findElement(firstRow);
driver.findElement(By.id("sort-by-date")).click();
// Wait until the old node is gone, then look up the new one
wait.until(ExpectedConditions.stalenessOf(before));
String text = driver.findElement(firstRow).getText();
Other patterns that help:
- Store
Bylocators, notWebElementfields, in page objects. Look the element up inside each method. - Wait for the update to finish (a spinner disappearing, a row count changing) before reading values.
- Avoid long-lived lists. Iterating over a
List<WebElement>while clicking items that trigger re-renders is a classic source of this error. Re-query by index or by a unique attribute on each pass.
Why Playwright rarely has this problem
A Playwright Locator is a query, not a node reference. It resolves the element again for every action and assertion, so a re-render between steps doesn’t break it. Playwright’s lower-level ElementHandle can still point at a detached node, which is one reason the documentation steers you towards locators.
Wrapping every call in a retry-on-stale loop makes the error go away but hides the real issue: the test is not waiting for the page to settle.