Answer
Handling StaleElementReferenceException
This exception occurs when a WebElement reference becomes stale — meaning the DOM has changed (page refresh, AJAX update, navigation) since the element was first found.
Cause
Java
WebElement btn = driver.findElement(By.id("submit")); // found element
driver.navigate().refresh(); // DOM rebuilt
btn.click(); // THROWS StaleElementReferenceException
Fix 1 — Re-find the element before use
Java
driver.navigate().refresh();
// Don't reuse old reference — find again
driver.findElement(By.id("submit")).click();
Fix 2 — Retry with try-catch
Java
public void clickWithRetry(By locator, int maxAttempts) {
for (int attempt = 0; attempt < maxAttempts; attempt++) {
try {
driver.findElement(locator).click();
return; // success
} catch (StaleElementReferenceException e) {
System.out.println("Stale element, retrying... attempt " + (attempt + 1));
}
}
throw new RuntimeException("Element still stale after " + maxAttempts + " attempts");
}
// Usage
clickWithRetry(By.id("submit"), 3);
Fix 3 — Wait for element staleness to resolve
Java
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
// Wait until element is no longer stale
wait.until(ExpectedConditions.refreshed(
ExpectedConditions.elementToBeClickable(By.id("submit"))
));
driver.findElement(By.id("submit")).click();
Fix 4 — Don't store elements across actions
Java
// Bad — storing element reference
WebElement row = driver.findElement(By.cssSelector(".data-row:first-child"));
performSomeAction(); // DOM may update
row.getText(); // Might be stale
// Good — re-find each time
performSomeAction();
String text = driver.findElement(By.cssSelector(".data-row:first-child")).getText();
When It Commonly Happens
- ✓After
driver.navigate().refresh() - ✓After AJAX/React/Angular DOM updates
- ✓After sorting or filtering a table
- ✓After navigating back with
driver.navigate().back() - ✓Frames reloading after interaction
