{"record":{"id":"16f0e18e5b5b4991","repo":"karatelabs/karate","slug":"locator-is-not-a-frame-locator","errorCode":null,"errorMessage":"locator is not a frame: {locator}","messagePattern":"locator is not a frame: (.+?)","errorType":"exception","errorClass":"DriverException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java","lineNumber":2326,"sourceCode":"\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;\n\n        // 1. Try standard, same-origin frames first\n        if (childFrames != null) {\n            for (Map<String, Object> frameData : childFrames) {\n                Map<String, Object> frame = (Map<String, Object>) frameData.get(\"frame\");","sourceCodeStart":2308,"sourceCodeEnd":2344,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java#L2308-L2344","documentation":"Karate's CDP driver resolves a frame locator by querying the page's frame tree. When the located node exists but the browser reports an 'error' entry instead of frame metadata, it means the locator matched a DOM node that is not an iframe/frame element, so it cannot be switched to.","triggerScenarios":"Calling driver.switchFrame() (or Scenario step * switchFrame) with a locator that resolves to a non-frame element, e.g. switchFrame('div.container') or switchFrame('#someDiv'); the CDP query returns {error: ...} for such nodes.","commonSituations":"Typo in a frame selector that accidentally matches a regular element; CSS/XPath too broad and matches an ancestor div; script executed against a page whose modal/overlay div shares a name with the intended frame; assuming an element embedded via shadow DOM or object/embed is a frame.","solutions":["Verify the locator actually targets an <iframe>/<frame> element (inspect in DevTools).","Use a more specific selector such as 'iframe[name=...]' or 'iframe#id' instead of a generic tag/class.","Use switchFrame with an index or a name/src that matches the frame's attributes.","Log/debug available frames first (e.g. evaluate window.frames lengths and names) before switching."],"exampleFix":"// before\ndriver.switchFrame('.modal-body');\n// after\ndriver.switchFrame('iframe.modal-frame'); // locator must match an <iframe>","handlingStrategy":"validation","validationCode":"// ensure the locator matches a frame before switching\nif (!locator.trim().toLowerCase().startsWith(\"iframe\") && !locator.contains(\"frame\")) {\n    throw new IllegalArgumentException(\"switchFrame locator must match an <iframe>/<frame>: \" + locator);\n}","typeGuard":null,"tryCatchPattern":"try {\n    driver.switchFrame(locator);\n} catch (Exception e) {\n    if (e.getMessage().startsWith(\"locator is not a frame\")) {\n        // fall back to iframe-specific selector\n        driver.switchFrame(\"iframe[name='main']\");\n    } else throw e;\n}","preventionTips":["Always scope frame locators to iframe/frame tags or use name/src/index forms.","Keep a map of frame names per page in test fixtures.","Inspect frame structure in DevTools before authoring the step.","Avoid generic class selectors when switching frames."],"tags":["driver","iframe","locator","cdp"],"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"}