karatelabs/karate · warning

frame context not received via event, falling back to…

Error message

frame context not received via event, falling back to isolated world: {}

What it means

When switching into a same-origin frame, CdpDriver waits up to 1s for the frame's main-world execution context to arrive via the Runtime.executionContextCreated event. If it never arrives, it logs this warning and falls back to creating an isolated world via Page.createIsolatedWorld so basic DOM access still works. Page-set variables (window.* from page scripts) will NOT be visible in that isolated world.

Solutions

  1. Retry the frame interaction after a short wait — once the frame's real context registers, subsequent evals hit the main world.
  2. Reload the page or re-navigate before switchFrame so the context event fires while the driver is listening.
  3. If you only need DOM reads, accept the isolated-world fallback; if you need page globals, wait for page readiness (e.g. waitForUrl) before switching frames.
  4. Check that the frame URL is stable — rapidly re-navigating frames keep invalidating contexts.

Example fix

// before
driver.switchFrame("#checkout-iframe");
String v = driver.script("document", "window.paymentConfig"); // may be null in isolated world
// after
driver.waitForUrl("**/checkout");
driver.switchFrame("#checkout-iframe");
String v = driver.script("document", "window.paymentConfig"); // main-world context now registered
Defensive patterns

Strategy: retry

Validate before calling

// only switch after the frame has fully loaded
driver.waitFor("iframe#app");
driver.waitForUrl("**/page-with-frame");

Try / catch

try {
    driver.switchFrame("iframe#app");
    String v = driver.script("document", "window.appState");
    if (v == null) { /* likely isolated-world fallback: retry after wait */ }
} catch (RuntimeException e) { /* retry switchFrame */ }

Prevention

When it happens

Trigger: switchFrame() into a frame whose main-world executionContextCreated event was not observed within the 1s bound — frames created before the driver attached, very fast navigations, or frames whose context creation raced the CDP event stream.

Common situations: Switching to iframes immediately after page load, attaching the driver mid-page-life so early frames' context events were missed, or heavy pages where the frame's script context starts late.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/1499bda6e8119bb1. Report an issue: GitHub.

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java:2531

        // First, wait for the main world context to arrive via Runtime.executionContextCreated —
        // event-completed future (awaitFrameContext), same pattern as the main frame's
        // mainContextReady, with the SAME 1s bound the old map-poll had so stranding can
        // never be worse than before.
        // IMPORTANT: Do NOT immediately fall back to Page.createIsolatedWorld - isolated worlds
        // are separate JS contexts where variables set by page scripts (e.g., window.frameValue)
        // are not visible. This caused flaky "Switch back to main frame" tests where
        // script('window.frameValue') returned null because it ran in an isolated world
        // instead of the iframe's main world.
        if (!frameContexts.containsKey(frameId)) {
            Integer contextId = awaitFrameContext(frameId, 1000);
            if (contextId != null) {
                logger.debug("frame context arrived via event: frameId={}", frameId);
            }
        }
        // Last resort: create an isolated world if the main world context never arrived.
        // This is less ideal (page-set variables won't be visible) but allows basic DOM access.
        if (!frameContexts.containsKey(frameId)) {
            logger.warn("frame context not received via event, falling back to isolated world: {}", frameId);
            try {
                CdpResponse response = cdp.method("Page.createIsolatedWorld")
                        .param("frameId", frameId)
                        .send();
                Integer contextId = response.getResult("executionContextId");
                if (contextId != null) {
                    frameContexts.put(frameId, contextId);
                    // Complete the readiness future too, so a concurrent waiter on the
                    // same frame observes the isolated world instead of timing out.
                    completeFrameContext(frameId, contextId);
                    logger.debug("created isolated world for frame {}: contextId={}", frameId, contextId);
                }
            } catch (Exception e) {
                logger.warn("failed to create isolated world for frame {}: {}", frameId, e.getMessage());
            }
        }

        // Verify the frame context is alive and ready for JS execution

View on GitHub (pinned to a22eb90246)