karatelabs/karate · error · DriverException
timeout waiting for element to be enabled
Error message
timeout waiting for element to be enabled: ${locator} What it means
CdpDriver.waitForEnabled(locator, timeout) polls until the element both exists and is enabled (per the browser's DOM disabled state). If the poll budget elapses without such an element, a DriverException is thrown with the locator embedded in the message. It is Karate's explicit signal that an element never became interactive within the allotted wait.
Solutions
- Increase the timeout argument or the driver retry/timeout configuration so slow renders are covered
- Verify the locator actually resolves (use exists(locator) or locateAll) before blaming enabled state
- If the element must be enabled programmatically, remove the disabled attribute via driver.script before waiting
- Click/wait on the element that enables it first (e.g. fill required fields) instead of waiting on a permanently disabled control
Example fix
// before
Element el = driver.waitForEnabled("#submit", Duration.ofSeconds(2));
// after
Element el = driver.waitForEnabled("#submit", Duration.ofSeconds(15)); Defensive patterns
Strategy: try-catch
Validate before calling
// before waiting, confirm the element exists
if (!driver.exists("#submit")) { throw new IllegalStateException("#submit not in DOM"); }
String disabled = (String) driver.script("#submit", "_.disabled");
if (Boolean.parseBoolean(String.valueOf(disabled))) { logger.warn("#submit currently disabled"); } Try / catch
try {
Element el = driver.waitForEnabled("#submit", Duration.ofSeconds(15));
} catch (DriverException e) {
logger.error("element never enabled: {} | url={}", e.getMessage(), driver.getUrl());
throw e;
} Prevention
- Always pass an explicit generous timeout instead of relying on the default
- Check exists() before waiting on enabled state to separate 'not found' from 'disabled'
- After a failure, dump the element's disabled attribute and page URL for diagnosis
When it happens
Trigger: Calling driver.waitForEnabled(locator, duration) (or the driver.waitForEnabled(locator) keyword with default timeout) when the element is absent, is disabled via the HTML 'disabled' attribute/property, or is inside a container Karate cannot reach before the timeout expires.
Common situations: Element is permanently disabled until a form is valid; element only appears after a slow AJAX call that exceeds the configured retry/timeout budget; wrong selector matches nothing; app rendered a disabled button due to a validation error the test did not anticipate; timeout too short on slow CI machines.
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
- timeout waiting for element
- timeout waiting for any element
- timeout waiting for text
- timeout waiting for elements
- element not found after
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/85afcd6d70a093e7.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java:3369
}
return found;
}
/**
* Wait for an element to be enabled.
*/
public Element waitForEnabled(String locator) {
return waitForEnabled(locator, options.getTimeoutDuration());
}
/**
* Wait for an element to be enabled with custom timeout.
*/
public Element waitForEnabled(String locator, Duration timeout) {
Element found = pollFor(timeout.toMillis(), options.getRetryInterval(),
() -> exists(locator) && enabled(locator) ? BaseElement.existing(this, locator) : null);
if (found == null) {
throw new DriverException("timeout waiting for element to be enabled: " + locator);
}
return found;
}
/**
* Wait for URL to contain expected string.
*/
public String waitForUrl(String expected) {
return waitForUrl(expected, options.getTimeoutDuration());
}
/**
* Wait for URL to contain expected string with custom timeout.
*/
public String waitForUrl(String expected, Duration timeout) {
String found = pollFor(timeout.toMillis(), options.getRetryInterval(), () -> {
String url = getUrl();
return url != null && url.contains(expected) ? url : null;View on GitHub (pinned to a22eb90246)