{"record":{"id":"3a7ce3b8947a4b43","repo":"karatelabs/karate","slug":"timeout-waiting-for-condition-expression","errorCode":null,"errorMessage":"timeout waiting for condition: ${expression}","messagePattern":"timeout waiting for condition: (.+?)","errorType":"exception","errorClass":"DriverException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java","lineNumber":3430,"sourceCode":"        }\n        return found;\n    }\n\n    /**\n     * Wait until a JavaScript expression evaluates to truthy.\n     */\n    public boolean waitUntil(String expression) {\n        return waitUntil(expression, options.getTimeoutDuration());\n    }\n\n    /**\n     * Wait until a JavaScript expression evaluates to truthy with custom timeout.\n     */\n    public boolean waitUntil(String expression, Duration timeout) {\n        boolean met = pollUntil(timeout.toMillis(), options.getRetryInterval(),\n                () -> Terms.isTruthy(script(expression)));\n        if (!met) {\n            throw new DriverException(\"timeout waiting for condition: \" + expression);\n        }\n        return true;\n    }\n\n    /**\n     * Wait until a supplier returns a truthy value.\n     */\n    public Object waitUntil(Supplier<Object> condition) {\n        return waitUntil(condition, options.getTimeoutDuration());\n    }\n\n    /**\n     * Wait until a supplier returns a truthy value with custom timeout.\n     */\n    public Object waitUntil(Supplier<Object> condition, Duration timeout) {\n        Object result = pollFor(timeout.toMillis(), options.getRetryInterval(), () -> {\n            Object r = condition.get();\n            return Terms.isTruthy(r) ? r : null;","sourceCodeStart":3412,"sourceCodeEnd":3448,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java#L3412-L3448","documentation":"CdpDriver.waitUntil(expression, timeout) polls a page-level JavaScript expression until it is truthy; if the poll budget expires it throws a DriverException with the expression text. Unlike the element variant, no locator is involved — the failure means the page state itself never satisfied the expression.","triggerScenarios":"driver.waitUntil(\"window.appReady === true\", duration) or a JS boolean condition that never becomes true — the script throws in-page each poll, returns undefined/false, or the timeout is too short.","commonSituations":"Waiting on a global flag the app sets only under conditions the test never triggers; JS runtime error inside the expression (accessing property of undefined); SPA hydration slower than the wait on CI; page navigated away so the expression evaluates in the wrong context.","solutions":["Run the expression manually in browser devtools on the failing page to check its value and syntax","Harden the expression against undefined intermediate objects (optional chaining)","Increase the timeout duration","Ensure prior steps actually trigger the state the expression watches"],"exampleFix":"// before\ndriver.waitUntil(\"window.config.loaded\", Duration.ofSeconds(5));\n// after\ndriver.waitUntil(\"window.config?.loaded === true\", Duration.ofSeconds(15));","handlingStrategy":"validation","validationCode":"// evaluate once and log before polling\nObject val = driver.script(\"window.config?.loaded === true\");\nlogger.debug(\"initial condition value={}\", val);","typeGuard":null,"tryCatchPattern":"try {\n    driver.waitUntil(\"window.config?.loaded === true\", Duration.ofSeconds(20));\n} catch (DriverException e) {\n    logger.error(\"page condition never truthy; val={}\", driver.script(\"window.config?.loaded\"));\n    throw e;\n}","preventionTips":["Harden expressions against undefined intermediates","Validate expression syntax in devtools on the same page build","Increase timeout for slow hydration/hydration-failed SPAs","Confirm preceding steps actually trigger the watched state"],"tags":["driver","timeout","javascript","wait-until"],"backgroundTag":"request-timeout","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}