{"record":{"id":"a690fe37b9ef851a","repo":"karatelabs/karate","slug":"failed-to-create-blank-tab-quitting-driver","errorCode":null,"errorMessage":"failed to create blank tab, quitting driver","messagePattern":"failed to create blank tab, quitting driver","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java","lineNumber":2758,"sourceCode":"        String nextTarget = null;\n        for (String pageId : allPages) {\n            if (!pageId.equals(targetToClose)) {\n                nextTarget = pageId;\n                break;\n            }\n        }\n        logger.debug(\"close() - switching to: {}\", nextTarget);\n\n        if (nextTarget == null) {\n            // Last tab - create a blank page to keep browser alive\n            // Uses browserMethod() because Target.createTarget is browser-level\n            CdpResponse response = cdp.browserMethod(\"Target.createTarget\")\n                    .param(\"url\", \"about:blank\")\n                    .send();\n            nextTarget = response.getResult(\"targetId\");\n            logger.debug(\"close() - created blank tab: {}\", nextTarget);\n            if (nextTarget == null) {\n                logger.warn(\"failed to create blank tab, quitting driver\");\n                quit();\n                return;\n            }\n        }\n\n        // Switch to another tab first (establishes new session)\n        activateTarget(nextTarget);\n        logger.debug(\"close() - switched to: {}, now closing: {}\", nextTarget, targetToClose);\n\n        // Register the removal future BEFORE sending closeTarget, then close.\n        // Target.closeTarget returns before the target is fully removed, so callers\n        // that enumerate tabs right after close() would still see the old one.\n        CompletableFuture<Void> removed = new CompletableFuture<>();\n        pendingTargetRemovals.put(targetToClose, removed);\n        try {\n            cdp.browserMethod(\"Target.closeTarget\")\n                    .param(\"targetId\", targetToClose)\n                    .send();","sourceCodeStart":2740,"sourceCodeEnd":2776,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java#L2740-L2776","documentation":"During close(), the driver first switches to a newly created blank tab (Target.createTarget with about:blank) so remaining pages can be torn down safely. If createTarget returns no targetId, the driver logs this warning and falls back to quit() — killing the whole browser instead of the graceful per-tab close. This means graceful close degraded to a hard shutdown.","triggerScenarios":"close() called while the browser process is dying/crashed, CDP browser-level websocket already broken, or a browser build/version where Target.createTarget fails (e.g. too many targets, profile locked).","commonSituations":"Calling driver.quit()/close() twice, browser crashed earlier in the test, killing the browser externally (taskkill/OOM) before close(), or Chromium builds with restrictive target limits.","solutions":["Nothing to fix if the browser is already gone — quit() is the correct fallback; check earlier logs for the root cause of the browser death.","Avoid double-close: guard with driver.isTerminated() or ensure quit() is called only once in teardown.","If the browser crashes often, check for OOM in CI, mismatched browser/Driver versions, or a corrupted user-data-dir.","Update Chrome/Chromium to a version compatible with the Karate release."],"exampleFix":"// before\n@After public void teardown() { driver.close(); driver.quit(); }\n// after\n@After public void teardown() { if (!driver.isTerminated()) { driver.quit(); } }","handlingStrategy":"fallback","validationCode":"if (driver.isTerminated()) { return; } // skip teardown if already dead","typeGuard":null,"tryCatchPattern":"try {\n    driver.close();\n} catch (RuntimeException e) {\n    // close() itself falls back to quit(); swallow secondary teardown errors\n    logger.warn(\"teardown issue ignored: {}\", e.getMessage());\n}","preventionTips":["Call quit() exactly once in teardown; guard with isTerminated()","Watch earlier logs for browser crashes (OOM, killed process)","Keep browser and Karate versions compatible","Avoid external process kills racing the driver's close path"],"tags":["cdp","browser-lifecycle","target-creation","close"],"backgroundTag":"browser-cdp-session-failure","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"}