grafana/k6 · error
getting text content of %q: %w
Error message
getting text content of %q: %w
What it means
Frame.TextContent() wraps the internal action as 'getting text content of "<selector>": <cause>'. The cause is typically a wait timeout (element never reached the attached state within opts.timeout), a strict-mode ambiguity, or a frame/context failure during evaluation.
Source
Thrown at internal/js/modules/k6/browser/common/frame.go:1848
opts.Force, withRetry, opts.NoWaitAfter, opts.Timeout,
)
if _, err := call(f.ctx, act, opts.Timeout); err != nil {
return errorFromDOMError(err)
}
return nil
}
// TextContent returns the textContent attribute of the first element found
// that matches the selector. The second return value is true if the returned
// text content is not null or empty, and false otherwise.
func (f *Frame) TextContent(selector string, popts *FrameTextContentOptions) (string, bool, error) {
f.log.Debugf("Frame:TextContent", "fid:%s furl:%q sel:%q", f.ID(), f.URL(), selector)
v, ok, err := f.textContent(selector, popts)
if err != nil {
return "", false, fmt.Errorf("getting text content of %q: %w", selector, err)
}
return v, ok, nil
}
func (f *Frame) textContent(selector string, opts *FrameTextContentOptions) (string, bool, error) {
TextContent := func(apiCtx context.Context, handle *ElementHandle) (any, error) {
return handle.textContent(apiCtx)
}
act := f.newAction(
selector, DOMElementStateAttached, opts.Strict, TextContent,
[]string{}, false, withRetry, true, opts.Timeout,
)
v, err := call(f.ctx, act, opts.Timeout)
if err != nil {
return "", false, errorFromDOMError(err)
}
if v == nil {View on GitHub (pinned to 93accf6570)
Solutions
- Prefer waiting for the content: const el = await frame.waitForSelector(sel); then el.textContent().
- Fix the selector to match exactly one node, or pass { strict: false } intentionally.
- Increase the timeout: frame.textContent(sel, { timeout: 60_000 }).
- Check page/frame state (isClosed/isDetached) if the failure is instant rather than after a timeout.
Example fix
// before
const t = await frame.textContent('.status'); // element not rendered yet
// after
const el = await frame.waitForSelector('.status');
const t = await el.textContent(); Defensive patterns
Strategy: try-catch
Validate before calling
const el = await frame.waitForSelector(sel, { state: 'attached' });
if (!el) throw new Error('element not attached'); Try / catch
try { return await frame.textContent(sel, { timeout: 60_000 }); }
catch (e) { if (/getting text content of/.test(e.message)) { return null; /* treat as absent */ } throw e; } Prevention
- waitForSelector before reading text on dynamic content
- Ensure selectors match exactly one node under strict mode
- Raise timeouts on slow CI environments
When it happens
Trigger: frame.textContent(sel) where the selector never matches within the timeout (default 30s); selector matches multiple elements with strict mode; frame navigated or detached while reading; page closed.
Common situations: Reading text of dynamically rendered content without waiting; wrong selector after a UI update; CI slowness making the default timeout too short.
Related errors
- unchecking %q: %w
- double clicking on %q: %w
- waiting for selector %q: %w
- finding iframe with selector %q: %w
- waiting for selector %q: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/b3d4fdb4f885f6c7.
Report an issue: GitHub.