{"record":{"id":"283b239218a88931","repo":"grafana/k6","slug":"getting-text-content-of-element-unexpected-type","errorCode":null,"errorMessage":"getting text content of element: unexpected type %T (expecting string)","messagePattern":"getting text content of element: unexpected type %T \\(expecting string\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/element_handle.go","lineNumber":1536,"sourceCode":"// The second return value is true if the text content exists, and false otherwise.\nfunc (h *ElementHandle) TextContent() (string, bool, error) {\n\ttextContent := func(apiCtx context.Context, handle *ElementHandle) (any, error) {\n\t\treturn handle.textContent(apiCtx)\n\t}\n\topts := NewElementHandleBaseOptions(h.DefaultTimeout())\n\ttextContentAction := h.newAction(\n\t\t[]string{}, textContent, opts.Force, withRetry, opts.NoWaitAfter, opts.Timeout,\n\t)\n\tv, err := call(h.ctx, textContentAction, opts.Timeout)\n\tif err != nil {\n\t\treturn \"\", false, fmt.Errorf(\"getting text content of element: %w\", err)\n\t}\n\tif v == nil {\n\t\treturn \"\", false, nil\n\t}\n\ts, ok := v.(string)\n\tif !ok {\n\t\treturn \"\", false, fmt.Errorf(\n\t\t\t\"getting text content of element: unexpected type %T (expecting string)\",\n\t\t\tv,\n\t\t)\n\t}\n\n\treturn s, true, nil\n}\n\n// Timeout will return the default timeout or the one set by the user.\n// It's an internal method not to be exposed as a JS API.\nfunc (h *ElementHandle) Timeout() time.Duration {\n\treturn h.DefaultTimeout()\n}\n\n// Type scrolls element into view, focuses element and types text.\nfunc (h *ElementHandle) Type(text string, opts *ElementHandleTypeOptions) error {\n\ttyp := func(apiCtx context.Context, handle *ElementHandle) (any, error) {\n\t\treturn nil, handle.typ(apiCtx, text, KeyboardOptions{})","sourceCodeStart":1518,"sourceCodeEnd":1554,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/element_handle.go#L1518-L1554","documentation":"Internal invariant break inside TextContent: the evaluation succeeded and returned a non-nil value, but it was not a Go string. The injected-script contract says textContent evaluation returns by-value strings; a number/bool/object result means the page-side evaluation behaved unexpectedly (e.g. page JavaScript overriding prototypes that the injected script relies on, or a divergent injected-script version).","triggerScenarios":"Page scripts polluting Object.prototype or Function prototypes that the injected script uses; execution-context weirdness after cross-origin iframe swaps returning handles instead of values; version mismatch between embedded injected_script.js and the Go wrapper.","commonSituations":"Testing third-party pages that patch built-ins; very old/new chromium builds against an unupdated k6; almost never seen on ordinary pages.","solutions":["Re-run once to rule out a transient context issue","If reproducible, capture K6_BROWSER_LOG=debug and report it as a k6 browser bug, including the %T type printed in the message","As a workaround, read the text via page.evaluate with document.querySelector(sel).textContent"],"exampleFix":"// workaround when textContent() keeps failing\nconst text = page.evaluate(() => document.querySelector('#el').textContent);","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  return el.textContent();\n} catch (e) {\n  if (String(e).includes('unexpected type')) {\n    // invariant break: fall back to in-page evaluation\n    return page.evaluate((s) => document.querySelector(s).textContent, sel);\n  }\n  throw e;\n}","preventionTips":["Treat a single occurrence as transient and retry","Avoid pages/scripts that patch built-in prototypes in the app under test","Keep k6 updated so the embedded injected script matches the wrapper"],"tags":["browser","internal","invariant","prototype-pollution"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}