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

  1. Verify the locator actually targets an <iframe>/<frame> element (inspect in DevTools).
  2. Use a more specific selector such as 'iframe[name=...]' or 'iframe#id' instead of a generic tag/class.
  3. Use switchFrame with an index or a name/src that matches the frame's attributes.
  4. 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

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


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)