grafana/k6 · error

execution context %q not found

Error message

execution context %q not found

What it means

Internal error from Frame.adoptBackendNodeID: the frame's execution-context map has no context for the requested world (main or utility) at lookup time. The map is populated when the browser sends Runtime.executionContextCreated and cleared on destruction, so the error means the world's context does not exist right now. Users normally hit it indirectly through element/handle operations that adopt a backend node.

Source

Thrown at internal/js/modules/k6/browser/common/frame.go:2252

	navOpts := &FrameWaitForNavigationOptions{
		URL:       urlPattern,
		Timeout:   opts.Timeout,
		WaitUntil: opts.WaitUntil,
	}
	_, err = f.WaitForNavigation(navOpts, rm)

	return err
}

func (f *Frame) adoptBackendNodeID(world executionWorld, id cdp.BackendNodeID) (*ElementHandle, error) {
	f.log.Debugf("Frame:adoptBackendNodeID", "fid:%s furl:%q world:%s id:%d", f.ID(), f.URL(), world, id)

	f.executionContextMu.RLock()
	defer f.executionContextMu.RUnlock()

	ec := f.executionContexts[world]
	if ec == nil {
		return nil, fmt.Errorf("execution context %q not found", world)
	}
	return ec.adoptBackendNodeID(id)
}

func (f *Frame) evaluate(
	apiCtx context.Context,
	world executionWorld,
	opts evalOptions, pageFunc string, args ...any,
) (any, error) {
	f.log.Debugf("Frame:evaluate", "fid:%s furl:%q world:%s opts:%s", f.ID(), f.URL(), world, opts)

	f.executionContextMu.RLock()
	defer f.executionContextMu.RUnlock()

	ec := f.executionContexts[world]
	if ec == nil {
		return nil, fmt.Errorf("execution context %q not found", world)
	}

View on GitHub (pinned to 93accf6570)

Solutions

  1. Re-acquire elements after every navigation instead of reusing handles from the previous document
  2. await page.waitForLoadState('domcontentloaded') before touching elements after goto
  3. Upgrade k6 — several execution-context race conditions in this area have been fixed in newer releases
  4. If it reproduces reliably, capture debug logs (--log-output=logger=stderr -v environment=DEBUG) and report with a minimal script

Example fix

// before
const btn = page.waitForSelector('#go');
await page.goto('https://example.com/next');
await btn.click(); // handle from previous document, context gone

// after
await page.goto('https://example.com/next');
const btn = page.waitForSelector('#go');
await btn.click();
Defensive patterns

Strategy: retry

Type guard

function isExecutionContextMissing(e) {
  return e instanceof Error && /execution context .* not found/.test(e.message);
}

Try / catch

async function withCtxRetry(fn, tries = 3) {
  for (let i = 0; i < tries; i++) {
    try { return await fn(); }
    catch (e) { if (isExecutionContextMissing(e) && i < tries - 1) continue; throw e; }
  }
}

Prevention

When it happens

Trigger: Adopting a node while the frame is mid-navigation (old contexts destroyed, new not yet created); operating on a frame that was just attached but whose utility world has not been initialized; pages where the utility world is not enabled; racing page.close().

Common situations: Element handles obtained before a navigation being used after it; k6 browser-module races around navigation in older versions (several were fixed over time); scripts that stash handles across page transitions.

Related errors


AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15). Data as JSON: /api/errors/063a39b9d71a5749. Report an issue: GitHub.