{"record":{"id":"3d73640387ddd412","repo":"grafana/k6","slug":"getting-text-content-of-element-w","errorCode":null,"errorMessage":"getting text content of element: %w","messagePattern":"getting text content of element: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/element_handle.go","lineNumber":1529,"sourceCode":"}\n\nfunc (h *ElementHandle) tap(_ context.Context, p *Position) error {\n\treturn h.frame.page.Touchscreen.tap(p.X, p.Y)\n}\n\n// TextContent returns the text content of the element.\n// 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 {","sourceCodeStart":1511,"sourceCodeEnd":1547,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/element_handle.go#L1511-L1547","documentation":"Wrapped failure from ElementHandle.TextContent (elementHandle.textContent()). The inner error comes from the action wrapper executing the textContent evaluation in the page: the element or its frame was detached, the execution context was destroyed by navigation, or the retry loop timed out (default element timeout, since this method uses NewElementHandleBaseOptions(h.DefaultTimeout())).","triggerScenarios":"Calling textContent() on a handle whose element was removed by an SPA re-render; calling it while the page is navigating (context destroyed); exceeding the default 30s timeout on very slow pages because the element never resolves to a stable state.","commonSituations":"Reading values from list rows that get virtualized/recycled; scraping content immediately after a click that triggers navigation instead of waiting for load; CI environments under load where evaluations are slow.","solutions":["Re-query the element right before reading: page.waitForSelector(sel, { state: 'attached' }).textContent()","If reading right after an action that navigates, await page.waitForNavigation() or page.waitForLoadState() first","Treat the nil-result case explicitly: textContent() returns (null, false, nil) when there is no text — do not confuse that benign case with this error","Increase the applicable browser timeout option if slowness is systemic"],"exampleFix":"// before\nconst el = page.$('.status');\nconst text = el.textContent(); // element detached by re-render\n\n// after\nconst text = page.waitForSelector('.status', { state: 'attached' }).textContent();","handlingStrategy":"try-catch","validationCode":"const el = page.waitForSelector('.status', { state: 'attached' });\n// reading is then safe; detached handles are the main failure source","typeGuard":"function hasText(result) {\n  return result === null || typeof result === 'string';\n}\n// const t = el.textContent(); if (!hasText(t)) throw new Error('unexpected content');","tryCatchPattern":"try {\n  return page.waitForSelector('.status', { state: 'attached' }).textContent();\n} catch (e) {\n  if (String(e).includes('getting text content')) {\n    return null; // element gone; treat as absent\n  }\n  throw e;\n}","preventionTips":["Re-query the element right before reading text","After clicks that navigate, waitForLoadState before reading","Remember textContent() returning null is success-with-no-text, not an error"],"tags":["browser","dom","text","detached-element","element-handle"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}