{"record":{"id":"3903cd952c5ef4df","repo":"karatelabs/karate","slug":"frame-not-found-locator","errorCode":null,"errorMessage":"frame not found: {locator}","messagePattern":"frame not found: (.+?)","errorType":"exception","errorClass":"DriverException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java","lineNumber":2321,"sourceCode":"            currentFrame = null;\n        }\n\n        // Wait for frame element to exist (same retry logic as other element operations)\n        retryIfNeeded(locator);\n\n        // Find the iframe element and get its frame ID\n        String js = Locators.wrapInFunctionInvoke(\n                \"var e = \" + Locators.selector(locator) + \";\" +\n                        \" if (!e) return null;\" +\n                        \" if (e.tagName !== 'IFRAME' && e.tagName !== 'FRAME') return { error: 'not a frame element' };\" +\n                        \" return { \" +\n                        \"   name: e.name || '',\" +\n                        \"   src: e.src || ''\" +\n                        \" }\");\n        Object result = script(js);\n\n        if (result == null) {\n            throw new DriverException(\"frame not found: \" + locator);\n        }\n\n        Map<String, Object> frameInfo = (Map<String, Object>) result;\n        if (frameInfo.containsKey(\"error\")) {\n            throw new DriverException(\"locator is not a frame: \" + locator);\n        }\n\n        // Get frame ID from frame tree by matching name or src\n        String targetName = (String) frameInfo.get(\"name\");\n        String targetSrc = (String) frameInfo.get(\"src\");\n\n        CdpResponse response = cdp.method(\"Page.getFrameTree\").send();\n        List<Map<String, Object>> childFrames = response.getResult(\"frameTree.childFrames\");\n\n        // Find matching frame in tree\n        String frameId = null;\n        String url = null;\n        String name = null;","sourceCodeStart":2303,"sourceCodeEnd":2339,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java#L2303-L2339","documentation":"When switching to a frame by locator, Karate runs an in-page script that matches iframe/frame elements by CSS, XPath, or wildcard and returns frame info (id, name, src). If the script returns null no matching element was found, and Karate throws this DriverException. If it returns an 'error' key instead, the element matched but is not a frame ('locator is not a frame').","triggerScenarios":"driver.switchFrame(locator) where no <iframe>/<frame> matches the given CSS/XPath/wildcard at evaluation time — wrong selector, frame not yet in DOM, frame nested inside another frame (the script only searches the current frame's document).","commonSituations":"Typos or wrong casing in CSS selectors; iframes added asynchronously by JS; trying to reach a nested iframe directly from the top frame; shadow-DOM-hosted iframes not reachable by plain CSS/XPath.","solutions":["Verify the selector matches an iframe/frame element in DevTools (document.querySelector) and fix the locator","Wait for the iframe to exist first (driver.waitFor(locator)) before switchFrame","For nested iframes, switch into the parent frame first, then switch again inside it","Use the iframe's name/id attribute as a simpler locator if available"],"exampleFix":"// before\ndriver.switchFrame(\"iframe#pay\"); // iframe not yet rendered\n// after\ndriver.waitFor(\"iframe#pay\");\ndriver.switchFrame(\"iframe#pay\");","handlingStrategy":"validation","validationCode":"Boolean present = (Boolean) driver.script(\"!!document.querySelector('\" + cssLocator + \"')\");\nif (present == null || !present) throw new IllegalStateException(\"iframe not in DOM yet: \" + cssLocator);","typeGuard":null,"tryCatchPattern":"try { driver.switchFrame(locator); } catch (DriverException e) { if (e.getMessage().startsWith(\"frame not found\")) { driver.waitFor(locator); driver.switchFrame(locator); } else if (e.getMessage().startsWith(\"locator is not a frame\")) { throw new IllegalArgumentException(\"selector must match iframe/frame: \" + locator); } else throw e; }","preventionTips":["Confirm the selector matches an iframe/frame element, not its container div","waitFor() the iframe before switching","Handle nested iframes by switching level by level","Prefer stable id/name attributes over generated class names in locators"],"tags":["cdp","iframe","locator","frame-switch"],"backgroundTag":"resource-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"}