grafana/k6 · error

setting content

Error message

setting content: %w

What it means

Thrown by k6 browser's frame.SetContent(html): it waits for the utility-world execution context, then evaluates document.open()/write()/close() with the new HTML. The error means that evaluation failed — the context was destroyed or the session died mid-write.

Solutions

  1. Settle navigation first: page.waitForLoadState('load') (or waitForNavigation) before setContent
  2. Check page.isClosed() and reopen the page if needed
  3. Retry setContent once after a settle — the race is transient
  4. Prefer goto('data:text/html,...') or a fixture URL when the content is fully static

Example fix

// before
page.setContent('<h1>hello</h1>');

// after
page.waitForLoadState('load');
let ok = false;
for (let i = 0; i < 2 && !ok; i++) {
  try { page.setContent('<h1>hello</h1>'); ok = true; }
  catch (e) { page.waitForLoadState('load'); }
}
Defensive patterns

Strategy: retry

Validate before calling

if (page.isClosed()) throw new Error('page closed; cannot setContent');
page.waitForLoadState('load');

Try / catch

const setContentSafe = (page, html, tries = 3) => {
  for (let i = 0; i < tries; i++) {
    try { page.setContent(html); return; }
    catch (e) {
      if (i === tries - 1) throw e;
      page.waitForLoadState('load');
    }
  }
};

Prevention

When it happens

Trigger: page.setContent(html) while the page is navigating (the context it waited for gets replaced), on a closed page, or when a race between waitForExecutionContext and the evaluate destroys the context.

Common situations: Calling setContent immediately after goto() without waiting for load; another frame/action triggering navigation concurrently; calling setContent on a page already closed by test end.

Related errors


AI-assisted analysis of grafana/k6@3fcf5388d7 (2026-08-18). Data as JSON: /api/errors/a4507e6889369be2. Report an issue: GitHub.

Appendix: source

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

	// TODO(@inancgumus): Respect the FrameSetContentOptions before executing the action.
	// A solution is similar to the logic in `WaitForLoadState`.

	js := `(html) => {
		window.stop();
		document.open();
		document.write(html);
		document.close();
	}`

	f.waitForExecutionContext(utilityWorld)

	eopts := evalOptions{
		forceCallable: true,
		returnByValue: true,
	}
	if _, err := f.evaluate(f.ctx, utilityWorld, eopts, js, html); err != nil {
		return fmt.Errorf("setting content: %w", err)
	}

	applySlowMo(f.ctx)

	return nil
}

// SetInputFiles sets input files for the selected element.
func (f *Frame) SetInputFiles(selector string, pfiles *Files, popts *FrameSetInputFilesOptions) error {
	f.log.Debugf("Frame:SetInputFiles", "fid:%s furl:%q sel:%q", f.ID(), f.URL(), selector)

	if err := f.setInputFiles(selector, pfiles, popts); err != nil {
		return fmt.Errorf("setting input files on %q: %w", selector, err)
	}

	applySlowMo(f.ctx)

	return nil

View on GitHub (pinned to 3fcf5388d7)