grafana/k6 · error
getting text content of element: unexpected type %T…
Error message
getting text content of element: unexpected type %T (expecting string)
What it means
Internal invariant error in the k6 browser module's ElementHandle.textContent(). The action succeeded and returned a non-nil value, but it was not a Go string (e.g., a sobek.Value or remote-object wrapper). Per the DOM spec element.textContent is string or null, and null is handled separately, so hitting this branch means an unexpected CDP/sobek serialization — an internal/module-level anomaly rather than a script mistake.
Solutions
- Upgrade (or roll back) k6 to a known-good release — this is a module defect, not a page condition.
- As a workaround, read the text via evaluation: const text = await el.eval('el => el.textContent').
- Report to the k6-browser repo with the k6 version and a minimal reproducer.
Example fix
// workaround: bypass textContent()'s internal conversion
const el = await page.waitForSelector('#status');
const text = await el.eval('el => el.textContent'); Defensive patterns
Strategy: fallback
Try / catch
try {
text = await el.textContent();
} catch (e) {
if (String(e).includes('unexpected type')) {
text = await el.eval('n => n.textContent'); // bypass internal conversion
} else { throw e; }
} Prevention
- Treat this error as a module/version defect: reproduce, then pin or upgrade k6.
- Have an el.eval fallback in shared helpers for text extraction.
When it happens
Trigger: CDP returning a value wrapper the module did not serialize to string (returnByValue path anomaly); version skew between k6 and its embedded browser module; a bug in the module's eval plumbing.
Common situations: Rare; typically after upgrading k6 to a version with a regression, or when a custom k6 build mixes browser module versions.
Related errors
- unpacking selected options
- checking hit target
- checking is in viewport: unexpected type %T
- getting element position
- getting injected script
AI-assisted analysis of grafana/k6@3fcf5388d7 (2026-08-18).
Data as JSON: /api/errors/283b239218a88931.
Report an issue: GitHub.
Appendix: source
Thrown at internal/js/modules/k6/browser/common/element_handle.go:1540
// The second return value is true if the text content exists, and false otherwise.
func (h *ElementHandle) TextContent() (string, bool, error) {
textContent := func(apiCtx context.Context, handle *ElementHandle) (any, error) {
return handle.textContent(apiCtx)
}
opts := NewElementHandleBaseOptions(h.DefaultTimeout())
textContentAction := h.newAction(
[]string{}, textContent, opts.Force, withRetry, opts.NoWaitAfter, opts.Timeout,
)
v, err := call(h.ctx, textContentAction, opts.Timeout)
if err != nil {
return "", false, fmt.Errorf("getting text content of element: %w", err)
}
if v == nil {
return "", false, nil
}
s, ok := v.(string)
if !ok {
return "", false, fmt.Errorf(
"getting text content of element: unexpected type %T (expecting string)",
v,
)
}
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 (h *ElementHandle) Timeout() time.Duration {
return h.DefaultTimeout()
}
// Type scrolls element into view, focuses element and types text.
func (h *ElementHandle) Type(text string, opts *ElementHandleTypeOptions) error {
typ := func(apiCtx context.Context, handle *ElementHandle) (any, error) {
return nil, handle.typ(apiCtx, text, KeyboardOptions{})View on GitHub (pinned to 3fcf5388d7)