{"record":{"id":"467ad52663dfbc39","repo":"karatelabs/karate","slug":"waituntil-timeout-expression","errorCode":null,"errorMessage":"waitUntil timeout: ${expression}","messagePattern":"waitUntil timeout: (.+?)","errorType":"exception","errorClass":"DriverException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/driver/w3c/W3cDriver.java","lineNumber":659,"sourceCode":"    public boolean waitUntil(String expression) {\n        return waitUntil(expression, options.getTimeoutDuration());\n    }\n\n    @Override\n    public boolean waitUntil(String expression, java.time.Duration timeout) {\n        long deadline = System.currentTimeMillis() + timeout.toMillis();\n        while (System.currentTimeMillis() < deadline) {\n            try {\n                Object result = eval(expression);\n                if (isTruthy(result)) {\n                    return true;\n                }\n            } catch (Exception e) {\n                // Ignore\n            }\n            sleep(options.getRetryInterval());\n        }\n        throw new DriverException(\"waitUntil timeout: \" + expression);\n    }\n\n    @Override\n    public Object waitUntil(java.util.function.Supplier<Object> condition) {\n        return waitUntil(condition, options.getTimeoutDuration());\n    }\n\n    @Override\n    public Object waitUntil(java.util.function.Supplier<Object> condition, java.time.Duration timeout) {\n        long deadline = System.currentTimeMillis() + timeout.toMillis();\n        while (System.currentTimeMillis() < deadline) {\n            Object result = condition.get();\n            if (isTruthy(result)) {\n                return result;\n            }\n            sleep(options.getRetryInterval());\n        }\n        throw new DriverException(\"waitUntil (supplier) timeout\");","sourceCodeStart":641,"sourceCodeEnd":677,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/driver/w3c/W3cDriver.java#L641-L677","documentation":"W3cDriver.waitUntil(expression) repeatedly evaluates a page-level JS expression (exceptions ignored each poll) until it returns truthy or the timeout elapses. If never truthy, a DriverException with the expression text is thrown. This variant is not scoped to an element.","triggerScenarios":"Calling driver.waitUntil(jsExpression) (or with explicit timeout) where the expression never evaluates truthy — e.g. waiting on window state, a JS variable, or document.readyState condition that never occurs.","commonSituations":"Waiting on a global JS variable the app never sets (script blocked/failed); expression syntax error so every poll throws and is swallowed; waiting for XHR completion flag that is only set on success while the request failed.","solutions":["Evaluate the expression via driver.script() once and inspect the actual value/error","Increase the timeout via waitUntil(expression, timeout)","Fix expression syntax — poll exceptions are silently ignored, so a broken expression just times out","Add an alternate condition (e.g. also detect the failure state) instead of only the success state"],"exampleFix":"// before\ndriver.waitUntil(\"window.appReady === true\"); // appReady never set, script failed\n// after\nString ready = driver.script(\"window.appReady === true\");\n// inspect ready, fix app bootstrap or use: driver.waitUntil(\"window.app && window.appReady === true\", 30000)","handlingStrategy":"validation","validationCode":"Object v = driver.script(expression); // evaluate once; check value/errors first","typeGuard":null,"tryCatchPattern":"try {\n    driver.waitUntil(expression, timeout);\n} catch (DriverException e) {\n    // run driver.script(expression) once to see the real value or JS error\n}","preventionTips":["A syntax error in the expression looks identical to a timeout — always dry-run it via driver.script()","Wait on conditions the app verifiably sets; add fallback failure-state checks","Keep expressions side-effect free so polling is safe"],"tags":["webdriver","timeout","javascript","wait"],"backgroundTag":"request-timeout","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}