{"record":{"id":"b30e18a69c78eecb","repo":"karatelabs/karate","slug":"element-not-found-locator","errorCode":null,"errorMessage":"Element not found: ${locator}","messagePattern":"Element not found: (.+?)","errorType":"exception","errorClass":"DriverException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/driver/w3c/W3cDriver.java","lineNumber":1049,"sourceCode":"        try {\n            Object result = session.executeScript(js);\n            if (W3cSession.isElementReference(result)) {\n                return W3cSession.elementIdFrom(result);\n            }\n        } catch (Exception e) {\n            logger.warn(\"locator failed, will retry once: {}\", e.getMessage());\n        }\n        // Single retry after sleep\n        sleep(options.getRetryInterval());\n        try {\n            Object result = session.executeScript(js);\n            if (W3cSession.isElementReference(result)) {\n                return W3cSession.elementIdFrom(result);\n            }\n        } catch (Exception e2) {\n            throw new DriverException(\"locator failed twice: \" + locator, e2);\n        }\n        throw new DriverException(\"Element not found: \" + locator);\n    }\n\n    /**\n     * Inject the Karate JS runtime (__kjs) into the browser if not already present.\n     * Same pattern as CdpDriver — loads driver.js from classpath resources.\n     * Provides wildcard locator resolution, shadow DOM traversal, and shared utilities.\n     */\n    private void ensureKjsRuntime() {\n        try {\n            // Guard on __kjs.resolve (the wildcard resolver), not merely __kjs — a co-installed\n            // helper may seed a partial window.__kjs without it; driver.js extends, never clobbers.\n            Object exists = session.executeScript(\n                    \"return typeof window.__kjs !== 'undefined' && typeof window.__kjs.resolve === 'function'\");\n            if (!Boolean.TRUE.equals(exists)) {\n                session.executeScript(DRIVER_JS);\n                logger.debug(\"Injected __kjs runtime into browser\");\n            }\n        } catch (Exception e) {","sourceCodeStart":1031,"sourceCodeEnd":1067,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/driver/w3c/W3cDriver.java#L1031-L1067","documentation":"W3cDriver throws DriverException 'Element not found: <locator>' when the locator script executed successfully on both attempts but never returned a valid WebDriver element reference. Unlike 'locator failed twice', the lookup itself worked — the element simply does not exist in the current DOM.","triggerScenarios":"Calling driver.locate/find (directly or via click/input/text APIs) with a selector that matches nothing in the current page; calling immediately after navigation before the element is rendered; locating inside a closed or wrong shadow root/iframe.","commonSituations":"Incorrect id/class/XPath after a UI redesign; SPA content not yet rendered (no wait); element is inside an iframe that wasn't switched into; dynamic ids that change per load.","solutions":["Add an explicit wait: use waitFor(locator) or waitUntil for the element/condition before interacting","Verify the selector in browser DevTools ($x / document.querySelector) on the exact page state","Switch into the correct iframe or pierce the correct shadow DOM if the element is nested","Fix the locator (stable attributes, data-testid) if the DOM changed"],"exampleFix":"// before\nString id = driver.text(\"#submit-btn\"); // throws if not yet rendered\n// after\ndriver.waitFor(\"#submit-btn\");\nString id = driver.text(\"#submit-btn\");","handlingStrategy":"validation","validationCode":"// ensure element exists before acting\ndriver.waitFor(locator); // throws only after the wait timeout","typeGuard":null,"tryCatchPattern":"try {\n    driver.text(locator);\n} catch (Exception e) {\n    if (e.getMessage().startsWith(\"Element not found\")) {\n        // handle absence explicitly instead of failing\n    }\n}","preventionTips":["Always use waitFor/waitUntil for dynamically rendered content","Test selectors in DevTools on the exact page state","Switch frames before locating nested elements","Prefer stable data-testid attributes over dynamic ids"],"tags":["webdriver","element-not-found","locator","timeout"],"backgroundTag":"entity-not-found","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"}