karatelabs/karate · error · DriverException
locator is not a frame
Error message
locator is not a frame: {locator} What it means
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.
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.
Example fix
// before
driver.switchFrame('.modal-body');
// after
driver.switchFrame('iframe.modal-frame'); // locator must match an <iframe> Defensive patterns
Strategy: validation
Validate before calling
// ensure the locator matches a frame before switching
if (!locator.trim().toLowerCase().startsWith("iframe") && !locator.contains("frame")) {
throw new IllegalArgumentException("switchFrame locator must match an <iframe>/<frame>: " + locator);
} Try / catch
try {
driver.switchFrame(locator);
} catch (Exception e) {
if (e.getMessage().startsWith("locator is not a frame")) {
// fall back to iframe-specific selector
driver.switchFrame("iframe[name='main']");
} else throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- frame not found
- {diagnostic: frame switch failed with child-frame url list}
- locator cannot be null or empty
- bad wildcard locator
- no frame at index: after retries
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/16f0e18e5b5b4991.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java:2326
// Find the iframe element and get its frame ID
String js = Locators.wrapInFunctionInvoke(
"var e = " + Locators.selector(locator) + ";" +
" if (!e) return null;" +
" if (e.tagName !== 'IFRAME' && e.tagName !== 'FRAME') return { error: 'not a frame element' };" +
" return { " +
" name: e.name || ''," +
" src: e.src || ''" +
" }");
Object result = script(js);
if (result == null) {
throw new DriverException("frame not found: " + locator);
}
Map<String, Object> frameInfo = (Map<String, Object>) result;
if (frameInfo.containsKey("error")) {
throw new DriverException("locator is not a frame: " + locator);
}
// Get frame ID from frame tree by matching name or src
String targetName = (String) frameInfo.get("name");
String targetSrc = (String) frameInfo.get("src");
CdpResponse response = cdp.method("Page.getFrameTree").send();
List<Map<String, Object>> childFrames = response.getResult("frameTree.childFrames");
// Find matching frame in tree
String frameId = null;
String url = null;
String name = null;
// 1. Try standard, same-origin frames first
if (childFrames != null) {
for (Map<String, Object> frameData : childFrames) {
Map<String, Object> frame = (Map<String, Object>) frameData.get("frame");View on GitHub (pinned to a22eb90246)