karatelabs/karate · error · DriverException
waitFor timeout
Error message
waitFor timeout: ${locator} What it means
W3cDriver.waitFor polls for the locator's existence every options.getRetryInterval() until the deadline (options.getTimeoutDuration()) elapses. If the element never exists within the timeout, a DriverException is thrown naming the locator. This is Karate's driver-level wait mechanism, distinct from UI implicit waits.
Solutions
- Verify the locator matches in the browser (devtools querySelector) and fix selector syntax
- Increase the timeout: waitFor(locator, 30000) or set the driver timeout option in karate-config
- If the element is inside an iframe/shadow DOM, switch context or use the appropriate locator strategy first
- If the element should genuinely not exist, use exists()/waitForAbsent-style logic instead of waitFor
Example fix
// before
Element el = driver.waitFor('#slow-widget'); // 10s default, SPA loads in 20s
// after
Element el = driver.waitFor('#slow-widget', 30000); Defensive patterns
Strategy: try-catch
Validate before calling
if (!driver.exists(locator)) {
// optionally poll manually or extend timeout before calling waitFor
} Try / catch
try {
Element el = driver.waitFor(locator, timeout);
} catch (DriverException e) {
// log driver.html('body') snapshot, fail or fall back
} Prevention
- Always pass an explicit timeout sized for your slowest environment
- Verify selectors in devtools before committing them to tests
- Switch to iframe/shadow context before waiting on nested elements
When it happens
Trigger: Calling driver.waitFor(locator) (or waitFor(locator, timeout)) when the element matching the locator is not present in the DOM at each poll within the timeout window; also triggered by a wrong selector, an element inside an unopened iframe, or a timeout too short for a slow page load.
Common situations: Wrong/typo'd selector; element rendered lazily by SPA after timeout; element in a shadow DOM or iframe not switched to; test env slower than CI defaults (timeout too small); selector targets an element removed before polling starts.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- waitForAny timeout
- waitForText timeout: expected
- waitForEnabled timeout
- waitUntil timeout: expression
- waitUntil timeout
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/c8bb65e06d954601.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/driver/w3c/W3cDriver.java:529
}
// ========== Wait Methods ==========
@Override
public Element waitFor(String locator) {
return waitFor(locator, options.getTimeoutDuration());
}
@Override
public Element waitFor(String locator, java.time.Duration timeout) {
long deadline = System.currentTimeMillis() + timeout.toMillis();
while (System.currentTimeMillis() < deadline) {
if (exists(locator)) {
return BaseElement.existing(this, locator);
}
sleep(options.getRetryInterval());
}
throw new DriverException("waitFor timeout: " + locator);
}
@Override
public Element waitForAny(String locator1, String locator2) {
return waitForAny(new String[]{locator1, locator2});
}
@Override
public Element waitForAny(String[] locators) {
return waitForAny(locators, options.getTimeoutDuration());
}
@Override
public Element waitForAny(String[] locators, java.time.Duration timeout) {
long deadline = System.currentTimeMillis() + timeout.toMillis();
while (System.currentTimeMillis() < deadline) {
for (String locator : locators) {
if (exists(locator)) {View on GitHub (pinned to a22eb90246)