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
- Wait for a real document: waitForLoadState('domcontentloaded') before content().
- Retry the call once after the page settles.
- 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
- Wait for domcontentloaded before serializing the DOM.
- Avoid content() during document replacement (redirects).
- Pin known-good k6 versions; report invariant failures upstream.
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
- getting bounding box of %q: unexpected type %T
- checking is %q checked: unexpected type %T
- unexpected type %T
- checking element is in viewport: unexpected type %T
- value %v out of range for int32 type
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/3697332caa1459c9.
Report an issue: GitHub.