grafana/k6 · error

getting frame content: expected string, got %T

Error message

getting frame content: expected string, got %T

What it means

Frame.Content() evaluates with returnByValue and expects a Go string back. If evaluation succeeded but the returned value is not a string (nil remote object, unexpected CDP type), this assertion fails. It is an internal contract violation between the serializer script and the evaluate pipeline rather than a user-input error.

Source

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

	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)

	return nil
}

View on GitHub (pinned to 93accf6570)

Solutions

  1. Wait for a real document: waitForLoadState('domcontentloaded') before content().
  2. Retry the call once after the page settles.
  3. If reproducible on a stable loaded page, report as a k6 browser module bug.

Example fix

// before
const html = page.content(); // called during document swap

// after
await page.waitForLoadState('domcontentloaded');
const html = page.content();
Defensive patterns

Strategy: try-catch

Validate before calling

await page.waitForLoadState('domcontentloaded');

Type guard

const isHtmlString = (s) => typeof s === 'string' && s.length > 0;

Try / catch

let html;
try {
  html = page.content();
} catch (e) {
  console.warn('content() returned non-string, retrying after load');
  await page.waitForLoadState('load');
  html = page.content();
}
if (!isHtmlString(html)) throw new Error('content still invalid');

Prevention

When it happens

Trigger: The page's document has no documentElement at serialization time (about:blank race, document being replaced mid-call); a module regression changing what Evaluate returns for returnByValue calls.

Common situations: Calling content() extremely early after page creation or during document replacement; k6 version upgrade introducing an evaluate regression.

Related errors


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