grafana/k6 · error

getting frame content: %w

Error message

getting frame content: %w

What it means

Frame.Content() serializes the document by evaluating a JS snippet (doctype + documentElement.outerHTML) through f.Evaluate. This error wraps a failure of that evaluation: the execution context was destroyed (navigation started), a CDP protocol error, or the JS throwing in the page.

Source

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

// Content returns the HTML content of the frame.
func (f *Frame) Content() (string, error) {
	f.log.Debugf("Frame:Content", "fid:%s furl:%q", f.ID(), f.URL())

	js := `() => {
		let content = '';
		if (document.doctype) {
			content = new XMLSerializer().serializeToString(document.doctype);
		}
		if (document.documentElement) {
			content += document.documentElement.outerHTML;
		}
		return content;
	}`

	v, err := f.Evaluate(js)
	if err != nil {
		return "", fmt.Errorf("getting frame content: %w", err)
	}
	s, ok := v.(string)
	if !ok {
		return "", fmt.Errorf("getting frame content: expected string, got %T", v)
	}

	return s, nil
}

// Dblclick double clicks an element matching provided selector.
func (f *Frame) Dblclick(selector string, popts *FrameDblclickOptions) error {
	f.log.Debugf("Frame:DblClick", "fid:%s furl:%q sel:%q", f.ID(), f.URL(), selector)

	if err := f.dblclick(selector, popts); err != nil {
		return fmt.Errorf("double clicking on %q: %w", selector, err)
	}

	applySlowMo(f.ctx)

View on GitHub (pinned to 93accf6570)

Solutions

  1. Wait for the navigation to settle: await page.waitForNavigation() or waitForLoadState('load') before content().
  2. Retry once — the new document's context will serve the next attempt.
  3. Avoid calling content() from racing async paths during navigation.

Example fix

// before
page.click('#download');
const html = page.content(); // mid-navigation -> context destroyed

// after
await page.click('#download');
await page.waitForLoadState('load');
const html = page.content();
Defensive patterns

Strategy: retry

Validate before calling

await page.waitForLoadState('load');

Try / catch

let html;
for (let i = 0; i < 3; i++) {
  try { html = page.content(); break; } catch (e) { await page.waitForLoadState('load'); }
}
if (!html) throw new Error('content() failed after retries');

Prevention

When it happens

Trigger: Calling content() while the page is navigating or immediately after a click that triggers navigation — the main-world execution context is torn down mid-evaluate; the target session is closing; the frame is detached.

Common situations: Capturing HTML right after page.goto() or a form submit without waiting; redirect chains; grabbing content in a callback that races navigation; iframe removed from DOM.

Related errors


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