grafana/k6 · error
getting frame title
Error message
getting frame title: %w
What it means
Thrown by k6 browser's frame.Title(): it evaluates `() => document.title` in the frame, and the evaluation itself failed. That means the frame's execution context was unavailable or destroyed — navigation in flight, frame detached, or page closed.
Solutions
- Wait for the page to settle: page.waitForLoadState('domcontentloaded') before title()
- Use waitForNavigation around actions that navigate, then read the title
- Skip stale frames: check frame.isDetached() if available, or re-list page.frames()
- Guard with page.isClosed() in teardown paths
Example fix
// before
const t = page.title();
// after
page.waitForLoadState('domcontentloaded');
const t = page.title(); Defensive patterns
Strategy: try-catch
Validate before calling
page.waitForLoadState('domcontentloaded');
if (page.isClosed()) throw new Error('page closed; cannot read title'); Type guard
const isTitle = (v) => typeof v === 'string';
Try / catch
let title = '';
try {
title = page.title();
} catch (e) {
console.log(`title read raced navigation: ${e}`);
page.waitForLoadState('domcontentloaded');
title = page.title();
} Prevention
- Read the title only after the navigation settles (waitForNavigation/waitForLoadState)
- Don't hold frame references across navigations
When it happens
Trigger: frame.title()/page.title() called during navigation (old context destroyed, new one not ready), on a detached frame (iframe removed from DOM), or after the page/target was closed.
Common situations: Asserting the title immediately after page.goto() before commit; reading titles of transient iframes that get removed; iterating page.frames() while the page mutates.
Related errors
- " " attribute is only supported for roles: "`).join(", ")}
- parsing frame navigation options to
- an error occurred communicating with k6 Cloud
- " " does not support " " matcher
- " " must be one of
AI-assisted analysis of grafana/k6@3fcf5388d7 (2026-08-18).
Data as JSON: /api/errors/34354da6793a11c8.
Report an issue: GitHub.
Appendix: source
Thrown at internal/js/modules/k6/browser/common/frame.go:1898
}
return s, true, nil
}
// Timeout will return the default timeout or the one set by the user.
// It's an internal method not to be exposed as a JS API.
func (f *Frame) Timeout() time.Duration {
return f.defaultTimeout()
}
// Title returns the title of the frame.
func (f *Frame) Title() (string, error) {
f.log.Debugf("Frame:Title", "fid:%s furl:%q", f.ID(), f.URL())
js := `() => document.title`
v, err := f.Evaluate(js)
if err != nil {
return "", fmt.Errorf("getting frame title: %w", err)
}
s, ok := v.(string)
if !ok {
return "", fmt.Errorf("getting frame title: expected string, got %T", v)
}
return s, nil
}
// Type text on the first element found matches the selector.
func (f *Frame) Type(selector, text string, popts *FrameTypeOptions) error {
f.log.Debugf("Frame:Type", "fid:%s furl:%q sel:%q text:%q", f.ID(), f.URL(), selector, text)
if err := f.typ(selector, text, popts); err != nil {
return fmt.Errorf("typing %q in %q: %w", text, selector, err)
}
applySlowMo(f.ctx)View on GitHub (pinned to 3fcf5388d7)