karatelabs/karate · error · DriverException
timeout waiting for condition
Error message
timeout waiting for condition '${expression}' on element: ${locator} What it means
CdpDriver.waitUntil(locator, expression, timeout) polls until the element exists AND the given JavaScript expression evaluated on that element is truthy; otherwise a DriverException naming the expression and locator is thrown. It is the generic per-element condition wait.
Solutions
- Test the expression directly with driver.script(locator, expression) and log the result to see what the page actually returns
- Verify the locator resolves and the expression returns a truthy JS value (true, non-empty string, non-zero number)
- Increase the timeout for genuinely slow async state
- Fix the preconditions (fill data, trigger event) so the condition can ever become true
Example fix
// before
driver.waitUntil("#status", "_.innerText == 'Done'", Duration.ofSeconds(3));
// after
String txt = (String) driver.script("#status", "_.innerText");
// log txt, correct expectation or timeout, e.g.:
driver.waitUntil("#status", "_.innerText.trim() == 'Done'", Duration.ofSeconds(15)); Defensive patterns
Strategy: validation
Validate before calling
// sanity-check the expression in-page before waiting
Object val = driver.script("#status", "_.innerText");
logger.debug("current status={}", val); Try / catch
try {
driver.waitUntil("#status", "_.innerText.trim() == 'Done'", Duration.ofSeconds(15));
} catch (DriverException e) {
Object cur = driver.script("#status", "_.innerText");
logger.error("condition not met; current value={}", cur);
throw e;
} Prevention
- Test the JS expression in browser devtools before embedding it
- Make expressions null-safe (optional chaining) so they return false instead of throwing
- Prefer boolean-producing expressions (=== true) over truthy guessing
- Use generous timeouts for backend-dependent state
When it happens
Trigger: driver.waitUntil(locator, expression, duration) where the element is missing, or the JS expression (e.g. "_.value != ''", "arguments[0].classList.contains('ready')") keeps evaluating false/throws in the page until the timeout elapses.
Common situations: Expression syntax not valid in the page context (returns undefined rather than true); waiting on a state a slow backend never delivers; wrong locator so script() fails silently each poll; app never reaches the expected state because of a bug or failed pre-step.
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 condition
- timeout waiting for condition
- element not found after
- karate.driver can only be read within a scenario
- retry FAILED after attempts: |
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/54256b8e1311266b.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java:3411
}
/**
* Wait until a JavaScript expression on an element evaluates to truthy.
* The element is available as '_' in the expression.
*/
public Element waitUntil(String locator, String expression) {
return waitUntil(locator, expression, options.getTimeoutDuration());
}
/**
* Wait until a JavaScript expression on an element evaluates to truthy.
*/
public Element waitUntil(String locator, String expression, Duration timeout) {
Element found = pollFor(timeout.toMillis(), options.getRetryInterval(),
() -> exists(locator) && Terms.isTruthy(script(locator, expression))
? BaseElement.existing(this, locator) : null);
if (found == null) {
throw new DriverException("timeout waiting for condition '" + expression + "' on element: " + locator);
}
return found;
}
/**
* Wait until a JavaScript expression evaluates to truthy.
*/
public boolean waitUntil(String expression) {
return waitUntil(expression, options.getTimeoutDuration());
}
/**
* Wait until a JavaScript expression evaluates to truthy with custom timeout.
*/
public boolean waitUntil(String expression, Duration timeout) {
boolean met = pollUntil(timeout.toMillis(), options.getRetryInterval(),
() -> Terms.isTruthy(script(expression)));
if (!met) {View on GitHub (pinned to a22eb90246)