grafana/k6 · error
unexpected type %T (expecting string)
Error message
unexpected type %T (expecting string)
What it means
After the innerHTML evaluation succeeds, k6 asserts the CDP result is a Go string; anything non-nil and non-string raises this invariant error. element.innerHTML is a string for real elements, so this fires when the handle points at a node without that property (text node, comment node) or when page scripts tamper with the DOM.
Solutions
- Make sure the selector matches an element node: check await el.evaluate(e => e.nodeType === Node.ELEMENT_NODE)
- Re-read via evaluation with a String() coercion: await el.evaluate(e => String(e.innerHTML))
- Use textContent() instead if you only need the node's content
Example fix
// before
const html = await el.innerHTML(); // handle is a text node
// after
if (!(await el.evaluate(e => e.nodeType === Node.ELEMENT_NODE))) {
throw new Error('handle is not an element node');
}
const html = await el.innerHTML(); Defensive patterns
Strategy: validation
Validate before calling
// Confirm the handle is an element node before innerHTML()
const isElement = await el.evaluate((e) => e.nodeType === Node.ELEMENT_NODE);
if (!isElement) {
throw new Error('handle is not an element node; innerHTML is undefined');
}
const html = await el.innerHTML(); Try / catch
try {
const html = await el.innerHTML();
} catch (e) {
if (/unexpected type/i.test(String(e.message))) {
const html = await el.evaluate((e2) => String(e2.innerHTML ?? ''));
} else throw e;
} Prevention
- Avoid evaluateHandle()-derived handles for innerHTML(); use selectors that match elements
- Check nodeType when handles come from XPath expressions that can match text nodes
When it happens
Trigger: The selector/handle resolved to a text or comment node rather than an element (e.g., a handle obtained from evaluate returning a node); SVG/MathML edge cases; pages overriding innerHTML via Object.defineProperty on prototypes.
Common situations: Handles produced by el.evaluateHandle(...) expressions that return nodes; XPath selectors matching text nodes; instrumented pages that redefine DOM properties. Rare on stock pages.
Related errors
- getting attribute of element: unexpected type %T (expecting…
- getting element's inner HTML
- an error occurred communicating with the provisioning API
- checking is in viewport: unexpected type %T
- converting result ( of type %t) to size
AI-assisted analysis of grafana/k6@3fcf5388d7 (2026-08-18).
Data as JSON: /api/errors/79057b393a6dfa7f.
Report an issue: GitHub.
Appendix: source
Thrown at internal/js/modules/k6/browser/common/element_handle.go:1004
// InnerHTML returns the inner HTML of the element.
func (h *ElementHandle) InnerHTML() (string, error) {
innerHTML := func(apiCtx context.Context, handle *ElementHandle) (any, error) {
return handle.innerHTML(apiCtx)
}
opts := NewElementHandleBaseOptions(h.DefaultTimeout())
innerHTMLAction := h.newAction(
[]string{}, innerHTML, opts.Force, withRetry, opts.NoWaitAfter, opts.Timeout,
)
v, err := call(h.ctx, innerHTMLAction, opts.Timeout)
if err != nil {
return "", fmt.Errorf("getting element's inner HTML: %w", err)
}
applySlowMo(h.ctx)
s, ok := v.(string)
if !ok {
return "", fmt.Errorf("unexpected type %T (expecting string)", v)
}
return s, nil
}
// InnerText returns the inner text of the element.
func (h *ElementHandle) InnerText() (string, error) {
innerText := func(apiCtx context.Context, handle *ElementHandle) (any, error) {
return handle.innerText(apiCtx)
}
opts := NewElementHandleBaseOptions(h.DefaultTimeout())
innerTextAction := h.newAction(
[]string{}, innerText, opts.Force, withRetry, opts.NoWaitAfter, opts.Timeout.Abs(),
)
v, err := call(h.ctx, innerTextAction, opts.Timeout)
if err != nil {
return "", fmt.Errorf("getting element's inner text: %w", err)
}View on GitHub (pinned to 3fcf5388d7)