{"record":{"id":"a0fea3ce67675f17","repo":"karatelabs/karate","slug":"dialog-is-blocking-runtime-evaluate","errorCode":null,"errorMessage":"dialog is blocking Runtime.evaluate","messagePattern":"dialog is blocking Runtime\\.evaluate","errorType":"exception","errorClass":"DialogOpenedException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java","lineNumber":1837,"sourceCode":"     */\n    private CdpResponse cdpEval(String expression) {\n        return cdpEval(expression, true);\n    }\n\n    /**\n     * As {@link #cdpEval(String)}, but lets the caller choose the serialization mode.\n     * {@code returnByValue=false} yields a CDP {@code RemoteObject} handle (its {@code objectId})\n     * instead of the value — required when the result is a live DOM node that a CDP domain method\n     * must address by reference (see {@link #objectId(String)}).\n     */\n    private CdpResponse cdpEval(String expression, boolean returnByValue) {\n        // Fail fast if a dialog is already open and blocking. A pre-existing\n        // unhandled dialog means any new Runtime.evaluate would be cancelled\n        // by our Page.javascriptDialogOpening handler (or hang until the 30s\n        // CDP timeout). Users should register onDialog() or call dialog(true|false)\n        // before further script activity.\n        if (dialogHandler == null && currentDialog != null && !currentDialog.isHandled()) {\n            throw new DialogOpenedException(\"dialog is blocking Runtime.evaluate\");\n        }\n        // A destroyed execution context (navigation tore it down) is re-created by Chrome\n        // within tens of milliseconds, NOT the 500ms element-poll interval. Sleeping the\n        // full retryInterval per transient error makes every post-navigation eval cost\n        // ~500ms+, and with wildcard locators / waitUntil polling that snowballs into\n        // spurious waitUntil/waitFor timeouts under parallel load. Poll fast instead, but\n        // keep the SAME overall time budget (retryCount * retryInterval) so a genuinely\n        // slow context swap on a loaded CI box still recovers.\n        int transientInterval = fastPollInterval();\n        int maxRetries = fastPollAttempts();\n\n        for (int attempt = 0; attempt <= maxRetries; attempt++) {\n            CdpMessage message = cdp.method(\"Runtime.evaluate\")\n                    .param(\"expression\", expression)\n                    .param(\"returnByValue\", returnByValue);\n\n            // Use explicit context ID for reliable frame targeting (see getFrameContext notes)\n            Integer contextId = getFrameContext();","sourceCodeStart":1819,"sourceCodeEnd":1855,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java#L1819-L1855","documentation":"Karate detected that a JavaScript dialog (alert/confirm/prompt/beforeunload) is currently open and unhandled. While such a dialog is open, Chrome cancels any Runtime.evaluate, so Karate fails fast with DialogOpenedException instead of hanging until the 30s CDP timeout. The fix on the user side is to register an onDialog handler or auto-answer dialogs via dialog(true|false).","triggerScenarios":"Calling driver.script(...)/script() (any JS evaluation) while a native dialog is open and no dialogHandler is registered and the current dialog has not been handled — e.g. the page popped an alert during a previous step.","commonSituations":"Pages with beforeunload prompts triggered by navigation; sites firing alert() during load or on click; forgetting to set dialog(false)/dialog(true) before interacting with dialog-heavy pages; parallel runs where one thread's dialog blocks subsequent script calls.","solutions":["Call driver.dialog(true) (accept) or driver.dialog(false) (dismiss) before steps that may open dialogs","Register an onDialog handler to programmatically handle dialogs as they appear","Dismiss the current dialog first (via the dialog API) before issuing further script() calls","If the dialog comes from beforeunload, use CDP Page.setBypassCSP or launch flags / evaluate-on-navigation settings to suppress it"],"exampleFix":"// before\ndriver.click(\"#delete-button\"); // fires confirm()\ndriver.script(\"document.title\"); // DialogOpenedException\n// after\ndriver.dialog(true); // auto-accept dialogs\ndriver.click(\"#delete-button\");\nString title = driver.script(\"document.title\");","handlingStrategy":"try-catch","validationCode":"// configure dialog auto-handling before any navigation\ndriver.dialog(false); // auto-dismiss all dialogs, prevents blocking","typeGuard":null,"tryCatchPattern":"try { String v = driver.script(expr); } catch (DialogOpenedException e) { driver.dialog(true); String v = driver.script(expr); }","preventionTips":["Always register onDialog() or set dialog(true|false) for pages known to open dialogs","Enable beforeunload suppression in test profiles","Never interleave script() calls between a click that may open a dialog and handling it","Handle dialogs immediately when tests trigger confirm/prompt flows"],"tags":["cdp","dialog","javascript-dialog","script"],"backgroundTag":"invalid-state-transition","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"}