karatelabs/karate · error · DriverException
Element not found
Error message
Element not found: ${locator} What it means
W3cDriver throws DriverException 'Element not found: <locator>' when the locator script executed successfully on both attempts but never returned a valid WebDriver element reference. Unlike 'locator failed twice', the lookup itself worked — the element simply does not exist in the current DOM.
Solutions
- Add an explicit wait: use waitFor(locator) or waitUntil for the element/condition before interacting
- Verify the selector in browser DevTools ($x / document.querySelector) on the exact page state
- Switch into the correct iframe or pierce the correct shadow DOM if the element is nested
- Fix the locator (stable attributes, data-testid) if the DOM changed
Example fix
// before
String id = driver.text("#submit-btn"); // throws if not yet rendered
// after
driver.waitFor("#submit-btn");
String id = driver.text("#submit-btn"); Defensive patterns
Strategy: validation
Validate before calling
// ensure element exists before acting driver.waitFor(locator); // throws only after the wait timeout
Try / catch
try {
driver.text(locator);
} catch (Exception e) {
if (e.getMessage().startsWith("Element not found")) {
// handle absence explicitly instead of failing
}
} Prevention
- Always use waitFor/waitUntil for dynamically rendered content
- Test selectors in DevTools on the exact page state
- Switch frames before locating nested elements
- Prefer stable data-testid attributes over dynamic ids
When it happens
Trigger: Calling driver.locate/find (directly or via click/input/text APIs) with a selector that matches nothing in the current page; calling immediately after navigation before the element is rendered; locating inside a closed or wrong shadow root/iframe.
Common situations: Incorrect id/class/XPath after a UI redesign; SPA content not yet rendered (no wait); element is inside an iframe that wasn't switched into; dynamic ids that change per load.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- element not found after
- timeout waiting for element
- waitFor timeout
- waitForAny timeout
- waitForText timeout: expected
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/b30e18a69c78eecb.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/driver/w3c/W3cDriver.java:1049
try {
Object result = session.executeScript(js);
if (W3cSession.isElementReference(result)) {
return W3cSession.elementIdFrom(result);
}
} catch (Exception e) {
logger.warn("locator failed, will retry once: {}", e.getMessage());
}
// Single retry after sleep
sleep(options.getRetryInterval());
try {
Object result = session.executeScript(js);
if (W3cSession.isElementReference(result)) {
return W3cSession.elementIdFrom(result);
}
} catch (Exception e2) {
throw new DriverException("locator failed twice: " + locator, e2);
}
throw new DriverException("Element not found: " + locator);
}
/**
* Inject the Karate JS runtime (__kjs) into the browser if not already present.
* Same pattern as CdpDriver — loads driver.js from classpath resources.
* Provides wildcard locator resolution, shadow DOM traversal, and shared utilities.
*/
private void ensureKjsRuntime() {
try {
// Guard on __kjs.resolve (the wildcard resolver), not merely __kjs — a co-installed
// helper may seed a partial window.__kjs without it; driver.js extends, never clobbers.
Object exists = session.executeScript(
"return typeof window.__kjs !== 'undefined' && typeof window.__kjs.resolve === 'function'");
if (!Boolean.TRUE.equals(exists)) {
session.executeScript(DRIVER_JS);
logger.debug("Injected __kjs runtime into browser");
}
} catch (Exception e) {View on GitHub (pinned to a22eb90246)