Skip to main content
SeleniumDecoded

Common Errors

Diagnose and fix the most common Selenium errors and exceptions.

Selenium 3 & 4 Stable

Understanding common Selenium errors helps you debug tests faster. This guide covers the most frequent exceptions and how to fix them.

NoSuchElementException

Cause: The element cannot be found in the DOM.

Fix NoSuchElementException
Selenium 3 & 4 Stable
// ERROR: NoSuchElementException - Element not found
// driver.findElement(By.id("nonexistent"));
// SOLUTIONS:
// 1. Add explicit wait - element may not be loaded yet
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement element = wait.until(
ExpectedConditions.presenceOfElementLocated(By.id("myElement"))
);
// 2. Check if element is in iframe
driver.switchTo().frame("iframeName");
WebElement element = driver.findElement(By.id("myElement"));
// 3. Verify locator in browser DevTools
// Right-click element > Inspect > Check actual id/class/etc.
// 4. Handle dynamic IDs
// Instead of: By.id("button_12345")
// Use: By.cssSelector("[id^='button_']") // Starts with
// Or: By.xpath("//button[contains(@id, 'button')]")
# ERROR: NoSuchElementException - Element not found
# driver.find_element(By.ID, "nonexistent")
# SOLUTIONS:
# 1. Add explicit wait - element may not be loaded yet
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
element = wait.until(
EC.presence_of_element_located((By.ID, "myElement"))
)
# 2. Check if element is in iframe
driver.switch_to.frame("iframeName")
element = driver.find_element(By.ID, "myElement")
# 3. Verify locator in browser DevTools
# Right-click element > Inspect > Check actual id/class/etc.
# 4. Handle dynamic IDs
# Instead of: By.ID, "button_12345"
# Use: By.CSS_SELECTOR, "[id^='button_']" # Starts with
# Or: By.XPATH, "//button[contains(@id, 'button')]"
// ERROR: NoSuchElementError - Element not found
// await driver.findElement(By.id('nonexistent'));
// SOLUTIONS:
// 1. Add explicit wait - element may not be loaded yet
const { until } = require('selenium-webdriver');
const element = await driver.wait(
until.elementLocated(By.id('myElement')),
10000
);
// 2. Check if element is in iframe
await driver.switchTo().frame('iframeName');
const element = await driver.findElement(By.id('myElement'));
// 3. Verify locator in browser DevTools
// Right-click element > Inspect > Check actual id/class/etc.
// 4. Handle dynamic IDs
// Instead of: By.id('button_12345')
// Use: By.css("[id^='button_']") // Starts with
// ERROR: NoSuchElementException - Element not found
// driver.FindElement(By.Id("nonexistent"));
// SOLUTIONS:
// 1. Add explicit wait - element may not be loaded yet
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement element = wait.Until(
d => d.FindElement(By.Id("myElement"))
);
// 2. Check if element is in iframe
driver.SwitchTo().Frame("iframeName");
IWebElement element = driver.FindElement(By.Id("myElement"));
// 3. Verify locator in browser DevTools
// Right-click element > Inspect > Check actual id/class/etc.
// 4. Handle dynamic IDs
// Instead of: By.Id("button_12345")
// Use: By.CssSelector("[id^='button_']") // Starts with

StaleElementReferenceException

Cause: The element reference is outdated because the DOM changed.

Fix StaleElementReferenceException
Selenium 3 & 4 Stable
// ERROR: StaleElementReferenceException
// The element was found, but the page refreshed or element was re-rendered
// WRONG - element reference becomes stale after page action
WebElement button = driver.findElement(By.id("submit"));
driver.navigate().refresh(); // Page refreshed
button.click(); // ERROR! Element is stale
// SOLUTION 1: Re-find the element after DOM changes
WebElement button = driver.findElement(By.id("submit"));
driver.navigate().refresh();
button = driver.findElement(By.id("submit")); // Re-find
button.click();
// SOLUTION 2: Use explicit wait for staleness then re-find
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement element = driver.findElement(By.id("dynamic"));
// Wait until element becomes stale, then find new one
wait.until(ExpectedConditions.stalenessOf(element));
element = wait.until(
ExpectedConditions.presenceOfElementLocated(By.id("dynamic"))
);
// SOLUTION 3: Retry pattern
public WebElement findWithRetry(By locator, int maxRetries) {
for (int i = 0; i < maxRetries; i++) {
try {
WebElement element = driver.findElement(locator);
element.isDisplayed(); // Verify element is valid
return element;
} catch (StaleElementReferenceException e) {
if (i == maxRetries - 1) throw e;
}
}
return null;
}
# ERROR: StaleElementReferenceException
# The element was found, but the page refreshed or element was re-rendered
# WRONG - element reference becomes stale after page action
button = driver.find_element(By.ID, "submit")
driver.refresh() # Page refreshed
button.click() # ERROR! Element is stale
# SOLUTION 1: Re-find the element after DOM changes
button = driver.find_element(By.ID, "submit")
driver.refresh()
button = driver.find_element(By.ID, "submit") # Re-find
button.click()
# SOLUTION 2: Use explicit wait for staleness then re-find
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
element = driver.find_element(By.ID, "dynamic")
# Wait until element becomes stale, then find new one
wait.until(EC.staleness_of(element))
element = wait.until(
EC.presence_of_element_located((By.ID, "dynamic"))
)
# SOLUTION 3: Retry pattern
def find_with_retry(driver, locator, max_retries=3):
for i in range(max_retries):
try:
element = driver.find_element(*locator)
element.is_displayed() # Verify element is valid
return element
except StaleElementReferenceException:
if i == max_retries - 1:
raise
return None
// ERROR: StaleElementReferenceError
// The element was found, but the page refreshed or element was re-rendered
// WRONG - element reference becomes stale after page action
let button = await driver.findElement(By.id('submit'));
await driver.navigate().refresh(); // Page refreshed
await button.click(); // ERROR! Element is stale
// SOLUTION 1: Re-find the element after DOM changes
let button = await driver.findElement(By.id('submit'));
await driver.navigate().refresh();
button = await driver.findElement(By.id('submit')); // Re-find
await button.click();
// SOLUTION 2: Retry pattern
async function findWithRetry(driver, locator, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const element = await driver.findElement(locator);
await element.isDisplayed(); // Verify element is valid
return element;
} catch (e) {
if (e.name === 'StaleElementReferenceError' && i < maxRetries - 1) {
continue;
}
throw e;
}
}
}
// ERROR: StaleElementReferenceException
// The element was found, but the page refreshed or element was re-rendered
// WRONG - element reference becomes stale after page action
IWebElement button = driver.FindElement(By.Id("submit"));
driver.Navigate().Refresh(); // Page refreshed
button.Click(); // ERROR! Element is stale
// SOLUTION 1: Re-find the element after DOM changes
IWebElement button = driver.FindElement(By.Id("submit"));
driver.Navigate().Refresh();
button = driver.FindElement(By.Id("submit")); // Re-find
button.Click();
// SOLUTION 2: Retry pattern
public IWebElement FindWithRetry(By locator, int maxRetries = 3)
{
for (int i = 0; i < maxRetries; i++)
{
try
{
IWebElement element = driver.FindElement(locator);
_ = element.Displayed; // Verify element is valid
return element;
}
catch (StaleElementReferenceException)
{
if (i == maxRetries - 1) throw;
}
}
return null;
}

ElementNotInteractableException

Cause: Element exists but cannot be interacted with (hidden, disabled, overlapped).

Fix ElementNotInteractableException
Selenium 3 & 4 Stable
// ERROR: ElementNotInteractableException
// Element is present but not clickable/typeable
// SOLUTION 1: Wait for element to be clickable
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement button = wait.until(
ExpectedConditions.elementToBeClickable(By.id("submit"))
);
button.click();
// SOLUTION 2: Scroll element into view
WebElement element = driver.findElement(By.id("footer-button"));
((JavascriptExecutor) driver).executeScript(
"arguments[0].scrollIntoView({block: 'center'});", element
);
element.click();
// SOLUTION 3: Wait for overlay/modal to disappear
wait.until(ExpectedConditions.invisibilityOfElementLocated(
By.cssSelector(".loading-overlay")
));
driver.findElement(By.id("submit")).click();
// SOLUTION 4: Use JavaScript click for stubborn elements
WebElement element = driver.findElement(By.id("hidden-button"));
((JavascriptExecutor) driver).executeScript("arguments[0].click();", element);
// SOLUTION 5: Check if element is in a disabled state
WebElement input = driver.findElement(By.id("email"));
if (!input.isEnabled()) {
// Element is disabled, handle accordingly
System.out.println("Element is disabled");
}
# ERROR: ElementNotInteractableException
# Element is present but not clickable/typeable
# SOLUTION 1: Wait for element to be clickable
wait = WebDriverWait(driver, 10)
button = wait.until(
EC.element_to_be_clickable((By.ID, "submit"))
)
button.click()
# SOLUTION 2: Scroll element into view
element = driver.find_element(By.ID, "footer-button")
driver.execute_script(
"arguments[0].scrollIntoView({block: 'center'});", element
)
element.click()
# SOLUTION 3: Wait for overlay/modal to disappear
wait.until(EC.invisibility_of_element_located(
(By.CSS_SELECTOR, ".loading-overlay")
))
driver.find_element(By.ID, "submit").click()
# SOLUTION 4: Use JavaScript click for stubborn elements
element = driver.find_element(By.ID, "hidden-button")
driver.execute_script("arguments[0].click();", element)
# SOLUTION 5: Check if element is in a disabled state
input_elem = driver.find_element(By.ID, "email")
if not input_elem.is_enabled():
print("Element is disabled")
// ERROR: ElementNotInteractableError
// Element is present but not clickable/typeable
// SOLUTION 1: Wait for element to be clickable
const button = await driver.wait(
until.elementIsEnabled(driver.findElement(By.id('submit'))),
10000
);
await button.click();
// SOLUTION 2: Scroll element into view
const element = await driver.findElement(By.id('footer-button'));
await driver.executeScript(
"arguments[0].scrollIntoView({block: 'center'});", element
);
await element.click();
// SOLUTION 3: Wait for overlay to disappear
await driver.wait(async () => {
const overlays = await driver.findElements(By.css('.loading-overlay'));
return overlays.length === 0 || !(await overlays[0].isDisplayed());
}, 10000);
// SOLUTION 4: Use JavaScript click for stubborn elements
const elem = await driver.findElement(By.id('hidden-button'));
await driver.executeScript("arguments[0].click();", elem);
// ERROR: ElementNotInteractableException
// Element is present but not clickable/typeable
// SOLUTION 1: Wait for element to be clickable
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement button = wait.Until(
d => {
var elem = d.FindElement(By.Id("submit"));
return elem.Displayed && elem.Enabled ? elem : null;
}
);
button.Click();
// SOLUTION 2: Scroll element into view
IWebElement element = driver.FindElement(By.Id("footer-button"));
((IJavaScriptExecutor)driver).ExecuteScript(
"arguments[0].scrollIntoView({block: 'center'});", element
);
element.Click();
// SOLUTION 3: Use JavaScript click for stubborn elements
IWebElement elem = driver.FindElement(By.Id("hidden-button"));
((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].click();", elem);

TimeoutException

Cause: A wait condition was not met within the timeout period.

Fix TimeoutException
Selenium 3 & 4 Stable
// ERROR: TimeoutException
// Element didn't appear within the wait time
// SOLUTION 1: Increase timeout for slow pages
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); // Longer timeout
WebElement element = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.id("slow-element"))
);
// SOLUTION 2: Add polling interval for dynamic content
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.pollingEvery(Duration.ofMillis(500)); // Check every 500ms
wait.ignoring(NoSuchElementException.class);
// SOLUTION 3: Use custom expected condition
WebElement element = wait.until(driver -> {
try {
WebElement el = driver.findElement(By.id("dynamic"));
return el.isDisplayed() && el.getText().length() > 0 ? el : null;
} catch (NoSuchElementException e) {
return null;
}
});
// SOLUTION 4: Check network/AJAX requests completed
wait.until(driver -> ((JavascriptExecutor) driver)
.executeScript("return document.readyState").equals("complete"));
# ERROR: TimeoutException
# Element didn't appear within the wait time
# SOLUTION 1: Increase timeout for slow pages
wait = WebDriverWait(driver, 30) # Longer timeout
element = wait.until(
EC.visibility_of_element_located((By.ID, "slow-element"))
)
# SOLUTION 2: Add polling interval for dynamic content
wait = WebDriverWait(driver, 10, poll_frequency=0.5) # Check every 500ms
# SOLUTION 3: Use custom expected condition
def element_has_text(locator):
def _predicate(driver):
try:
element = driver.find_element(*locator)
return element if element.is_displayed() and element.text else None
except NoSuchElementException:
return None
return _predicate
element = wait.until(element_has_text((By.ID, "dynamic")))
# SOLUTION 4: Check network/AJAX requests completed
wait.until(lambda d: d.execute_script("return document.readyState") == "complete")
// ERROR: TimeoutError
// Element didn't appear within the wait time
// SOLUTION 1: Increase timeout for slow pages
const element = await driver.wait(
until.elementLocated(By.id('slow-element')),
30000 // 30 seconds
);
// SOLUTION 2: Custom wait condition
const element = await driver.wait(async () => {
try {
const el = await driver.findElement(By.id('dynamic'));
const text = await el.getText();
return (await el.isDisplayed()) && text.length > 0 ? el : null;
} catch (e) {
return null;
}
}, 10000);
// SOLUTION 3: Check network/AJAX requests completed
await driver.wait(async () => {
return await driver.executeScript('return document.readyState') === 'complete';
}, 10000);
// ERROR: WebDriverTimeoutException
// Element didn't appear within the wait time
// SOLUTION 1: Increase timeout for slow pages
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
IWebElement element = wait.Until(
d => d.FindElement(By.Id("slow-element"))
);
// SOLUTION 2: Custom wait condition
wait.Until(d => {
try
{
var el = d.FindElement(By.Id("dynamic"));
return el.Displayed && !string.IsNullOrEmpty(el.Text) ? el : null;
}
catch (NoSuchElementException)
{
return null;
}
});
// SOLUTION 3: Check document ready state
wait.Until(d =>
((IJavaScriptExecutor)d).ExecuteScript("return document.readyState")
.Equals("complete")
);

WebDriverException: Session Not Created

Cause: Browser/driver version mismatch or browser not installed.

Terminal window
# Check browser version
google-chrome --version
chromedriver --version
# Download matching driver from:
# https://chromedriver.chromium.org/downloads
# https://github.com/mozilla/geckodriver/releases
# Or use WebDriverManager (Java)
# pip install webdriver-manager (Python)
Auto-manage Driver Version
Selenium 3 & 4 Stable
// Use WebDriverManager to auto-download correct driver
import io.github.bonigarcia.wdm.WebDriverManager;
// Setup - downloads correct ChromeDriver automatically
WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver();
// For Firefox
WebDriverManager.firefoxdriver().setup();
WebDriver driver = new FirefoxDriver();
# Use webdriver-manager to auto-download correct driver
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
# Setup - downloads correct ChromeDriver automatically
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
# For Firefox
from webdriver_manager.firefox import GeckoDriverManager
service = Service(GeckoDriverManager().install())
driver = webdriver.Firefox(service=service)
// In Node.js, use selenium-webdriver's built-in manager
// or specify path to manually downloaded driver
const { Builder } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
// selenium-webdriver 4.x manages drivers automatically
const driver = await new Builder()
.forBrowser('chrome')
.build();
// Use WebDriverManager.Net
// Install-Package WebDriverManager
using WebDriverManager;
using WebDriverManager.DriverConfigs.Impl;
// Setup - downloads correct driver automatically
new DriverManager().SetUpDriver(new ChromeConfig());
IWebDriver driver = new ChromeDriver();
// For Firefox
new DriverManager().SetUpDriver(new FirefoxConfig());
IWebDriver driver = new FirefoxDriver();

Quick Reference Table

ErrorCommon CauseQuick Fix
NoSuchElementExceptionElement not in DOMAdd explicit wait
StaleElementReferenceExceptionDOM changed after findRe-find element
ElementNotInteractableExceptionElement hidden/disabledWait for clickable, scroll
TimeoutExceptionWait condition not metIncrease timeout, check locator
InvalidSelectorExceptionBad CSS/XPath syntaxValidate selector in DevTools
NoSuchWindowExceptionWindow was closedSwitch to valid window
NoSuchFrameExceptionFrame doesn’t existVerify frame name/id
SessionNotCreatedExceptionDriver/browser mismatchUpdate driver version

Debugging Checklist

  1. Check locator - Verify in browser DevTools (F12)
  2. Add wait - Element may need time to load
  3. Check visibility - Element might be hidden or overlapped
  4. Check context - Is element in iframe or shadow DOM?
  5. Check timing - Is there a race condition?
  6. Check driver version - Does it match browser?

Next Steps