grafana/k6 · error

evaluating handle for frame: execution context %q not found

Error message

evaluating handle for frame: execution context %q not found

What it means

Frame.EvaluateHandle() waits for the main-world execution context, then looks it up under f.executionContexts[mainWorld]. If the map entry is still nil after the wait (context destroyed by navigation, frame detached, or context creation racing), this error is returned. The waitForExecutionContext call right above shows the module already tried to let the context appear.

Source

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

	}
	if exceptionDetails != nil {
		return fmt.Errorf("%s", parseExceptionDetails(exceptionDetails))
	}

	return nil
}

// EvaluateHandle will evaluate provided page function within an execution context.
func (f *Frame) EvaluateHandle(pageFunc string, args ...any) (handle JSHandleAPI, _ error) {
	f.log.Debugf("Frame:EvaluateHandle", "fid:%s furl:%q", f.ID(), f.URL())

	evalHandle := func() (JSHandleAPI, error) {
		f.executionContextMu.RLock()
		defer f.executionContextMu.RUnlock()

		ec := f.executionContexts[mainWorld]
		if ec == nil {
			return nil, fmt.Errorf("evaluating handle for frame: execution context %q not found", mainWorld)
		}
		return ec.EvalHandle(f.ctx, pageFunc, args...) //nolint:wrapcheck
	}

	f.waitForExecutionContext(mainWorld)
	handle, err := evalHandle()
	if err != nil {
		return nil, fmt.Errorf("evaluating handle for frame: %w", err)
	}

	applySlowMo(f.ctx)

	return handle, nil
}

// Fill fills out the first element found that matches the selector.
func (f *Frame) Fill(selector, value string, popts *FrameFillOptions) error {
	f.log.Debugf("Frame:Fill", "fid:%s furl:%q sel:%q val:%q", f.ID(), f.URL(), selector, value)

View on GitHub (pinned to 93accf6570)

Solutions

  1. Wait for a concrete document state first: await page.waitForLoadState('domcontentloaded') before EvaluateHandle.
  2. Retry once after a short delay — the context usually registers immediately after.
  3. If working in an iframe, obtain the frame after it is attached and wait on it.

Example fix

// before
const h = page.evaluateHandle('() => window'); // right after goto, main world missing

// after
await page.waitForLoadState('domcontentloaded');
const h = page.evaluateHandle('() => window');
Defensive patterns

Strategy: retry

Validate before calling

await page.waitForLoadState('domcontentloaded');

Try / catch

let h;
for (let i = 0; i < 3; i++) {
  try { h = page.evaluateHandle(pageFunc); break; } catch (e) { await sleep(500); }
}
if (!h) throw new Error('evaluateHandle failed: no execution context');

Prevention

When it happens

Trigger: Calling EvaluateHandle immediately after page.goto()/frame creation before the main world is created; the frame navigates so the previous context is nulled and the new one has not registered; the frame (iframe) gets detached.

Common situations: Early-script races on about:blank; redirect chains nulling contexts; OOPIF iframes with slow context creation; heavy parallelism slowing context registration.

Related errors


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