Stale Element Exception in Selenium
Stale means old, decayed, or no longer fresh.
StaleElementReferenceException is thrown when a WebElement object you previously found no longer exists in the DOM, typically because:
- ✓The page was refreshed
- ✓An AJAX call updated the DOM
- ✓Navigation occurred after finding the element
- ✓The element was removed and re-added to the DOM
How it happens:
WebElement element = driver.findElement(By.id("myElement"));
// Page refreshes or DOM updates...
element.click(); // StaleElementReferenceException thrown here!
Solution 1 — Re-find the element:
// Instead of caching the element, find it fresh each time
driver.findElement(By.id("myElement")).click();
Solution 2 — Catch and re-find:
try {
WebElement element = driver.findElement(By.id("myElement"));
element.click();
} catch (StaleElementReferenceException e) {
// Re-find and retry
driver.findElement(By.id("myElement")).click();
}
Solution 3 — Retry loop:
int maxRetries = 3;
for (int i = 0; i < maxRetries; i++) {
try {
WebElement element = driver.findElement(By.id("myElement"));
element.click();
break; // Success — exit loop
} catch (StaleElementReferenceException e) {
if (i == maxRetries - 1) throw e;
Thread.sleep(500);
}
}
Solution 4 — Wait for element to be fresh:
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement element = wait.until(
ExpectedConditions.refreshed(
ExpectedConditions.elementToBeClickable(By.id("myElement"))
)
);
element.click();
Solution 5 — Use ExpectedConditions.stalenessOf():
WebElement element = driver.findElement(By.id("myElement"));
// Wait for the stale element to disappear, then re-find
wait.until(ExpectedConditions.stalenessOf(element));
element = driver.findElement(By.id("myElement"));
element.click();
Common scenarios causing StaleElementException:
| Scenario | Why it happens |
|---|---|
| Page refresh | Old element reference invalid |
| AJAX/dynamic content | DOM modified, element re-rendered |
| Navigation (back/forward) | New page, old references invalid |
| Angular/React re-render | Component re-created after state change |
Best practice: Avoid caching WebElement objects across interactions that might change the DOM. Prefer calling driver.findElement() immediately before each interaction.
