{"record":{"id":"067b05630519f0ff","repo":"grafana/k6","slug":"checking-state-q-of-element-q","errorCode":null,"errorMessage":"checking state %q of element %q","messagePattern":"checking state %q of element %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/element_handle.go","lineNumber":205,"sourceCode":"\t\t\treturn injected.checkElementState(node, state);\n\t\t}\n\t`\n\topts := evalOptions{\n\t\tforceCallable: true,\n\t\treturnByValue: true,\n\t}\n\tresult, err := h.evalWithScript(h.ctx, opts, fn, state)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tswitch v := result.(type) {\n\tcase string: // An error happened (returned as \"error:...\" from JS)\n\t\treturn nil, errorFromDOMError(v)\n\tcase bool:\n\t\treturn &v, nil\n\t}\n\n\treturn nil, fmt.Errorf(\n\t\t\"checking state %q of element %q\", state, reflect.TypeOf(result))\n}\n\nfunc (h *ElementHandle) click(p *Position, opts *MouseClickOptions) error {\n\treturn h.frame.page.Mouse.click(p.X, p.Y, opts)\n}\n\n// This will get the clickable point of the element relative to the page even\n// when the element is in an iframe. In some cases this isn't the case and we\n// need to translate the point to the page.\nfunc (h *ElementHandle) clickablePoint() (*Position, error) {\n\tr, err := h.BoundingBox()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"finding clickable point: %w\", err)\n\t}\n\treturn &Position{X: r.X + r.Width/2, Y: r.Y + r.Height/2}, nil\n}\n","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/element_handle.go#L187-L223","documentation":"checkElementState evaluates injected.checkElementState(node, state) and expects either a string 'error:*' or a bool. If the JS side returns anything else (null/undefined/number), k6 reports 'checking state <state> of element <Go type>' — an internal contract violation between k6 and its injected script, usually triggered when the element or frame became invalid during evaluation.","triggerScenarios":"Waiting for an element state (visible/hidden/enabled/disabled/stable — used by waitFor and actionability checks before click/fill) when the frame navigates or the node is detached mid-evaluation so the injected script returns undefined instead of a bool; or a k6 version whose injected script bundle is out of sync.","commonSituations":"Auto-waiting on elements in SPAs that re-render aggressively; navigations racing actionability checks; upgrading k6 with a stale cached browser profile; extremely rare on healthy pages.","solutions":["Retry the waiting/action once after re-acquiring the locator — detached-node evaluations are transient.","Upgrade to the latest k6 release to rule out an injected-script/binary mismatch.","Avoid initiating actions exactly when a navigation is expected (wait for URL/content stability first).","If reproducible on a static page, file a k6 issue with the script and browser version."],"exampleFix":"// before\nawait page.locator('#status').click();  // actionability wait hits unexpected JS result\n// -> checking state \"visible\" of element \"<nil>\"\n\n// after\nconst loc = page.locator('#status');\nawait loc.waitFor({ state: 'visible' });\ntry { await loc.click(); }\ncatch (e) {\n  if (!String(e).includes('checking state')) throw e;\n  await page.locator('#status').click(); // re-acquire and retry\n}","handlingStrategy":"retry","validationCode":"// make the wait state explicit and re-acquire the locator, keeping handles short-lived\nawait page.locator(sel).waitFor({ state: 'visible', timeout: 10_000 });\nawait page.locator(sel).click();","typeGuard":null,"tryCatchPattern":"try {\n  await page.locator(sel).click();\n} catch (e) {\n  if (/checking state .* of element/.test(String(e))) {\n    // injected-script contract broke (frame/node churn) — re-acquire and retry once\n    await page.locator(sel).waitFor({ state: 'visible' });\n    await page.locator(sel).click();\n  } else {\n    throw e;\n  }\n}","preventionTips":["Keep element handles/locators short-lived in re-rendering SPAs; re-query before acting.","Stay on the latest k6 release so the injected script bundle and binary stay in sync.","Separate navigation phases from interaction phases to avoid evaluations racing navigation."],"tags":["element-handle","state","wait","actionability","internal"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}