{"record":{"id":"1f451d4b256d7aec","repo":"CloakHQ/CloakBrowser","slug":"element-selector-failed-enabled-check-element","errorCode":null,"errorMessage":"Element ${selector} failed enabled check: element is disabled","messagePattern":"Element (.+?) failed enabled check: element is disabled","errorType":"exception","errorClass":"ElementNotEnabledError","httpStatus":null,"severity":"error","filePath":"js/src/human/actionability.ts","lineNumber":120,"sourceCode":"// ---------------------------------------------------------------------------\n// Pre-scroll actionability\n// ---------------------------------------------------------------------------\n\nasync function stealthActionable(\n  pageOrFrame: Page | Frame,\n  selector: string,\n  checks: ReadonlySet<CheckName>,\n): Promise<void> {\n  const world = getWorld(pageOrFrame);\n  if (!world) throw new StealthWorldUnavailableError();\n\n  const { status, data } = await evalParsed(world, buildActionableJs(selector));\n  if (status === UNSUPPORTED) throw new UnsupportedHumanizeSelectorError(selector);\n  if (status === EVALUATION_FAILED) throw new StealthEvaluationError(selector);\n  if (status === NOT_FOUND) throw new ElementNotAttachedError(selector);\n  if (status !== OK || !data) throw new StealthEvaluationError(selector);\n  if (checks.has('visible') && !data.visible) throw new ElementNotVisibleError(selector);\n  if (checks.has('enabled') && !data.enabled) throw new ElementNotEnabledError(selector);\n  if (checks.has('editable') && !data.editable) throw new ElementNotEditableError(selector);\n}\n\nasync function readBox(\n  pageOrFrame: Page | Frame,\n  selector: string,\n): Promise<{ x: number; y: number; width: number; height: number } | null> {\n  const world = getWorld(pageOrFrame);\n  if (!world) throw new StealthWorldUnavailableError();\n\n  const { status, data } = await evalParsed(world, buildBoxJs(selector));\n  if (status === OK && data?.box) return data.box;\n  if (status === NOT_FOUND) return null;\n  if (status === UNSUPPORTED) throw new UnsupportedHumanizeSelectorError(selector);\n  throw new StealthEvaluationError(selector);\n}\n\nexport async function ensureActionable(","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/CloakHQ/CloakBrowser/blob/d6bad5de261bedf025280ace1d14e800aee13923/js/src/human/actionability.ts#L102-L138","documentation":"With 'enabled' in the requested checks, the probe found the element but data.enabled === false — a disabled control (disabled attribute, aria-disabled, or fieldset[disabled] ancestry).","triggerScenarios":"ensureActionable with 'enabled' (part of default checks for click/type/fill/clear) on a disabled button/input, e.g. a submit button disabled until form validity, or an input disabled during in-flight submission.","commonSituations":"Submitting before required fields are filled, buttons gated behind async loading/ToS checkbox, disabled state lingering after a failed request, or fieldset-level disable during form submission.","solutions":["Satisfy the gating condition first (fill required inputs, accept checkbox, await loading completion)","Await the enabled state before acting: expect(locator).toBeEnabled()","Retry with backoff when the disabled state depends on an async backend call","Drop the 'enabled' check explicitly if acting on disabled controls is intentional"],"exampleFix":"// before\nawait humanClick(page, '#submit');\n// after\nawait humanFill(page, '#email', 'a@b.c');\nawait humanFill(page, '#password', 'secret');\nawait page.waitForFunction(() => !(document.querySelector('#submit') as HTMLButtonElement).disabled);\nawait humanClick(page, '#submit');","handlingStrategy":"retry","validationCode":"await page.waitForFunction((s) => { const el = document.querySelector(s); return !!el && !(el as HTMLButtonElement).disabled; }, sel, { timeout: 5000 });","typeGuard":"function isElementNotEnabledError(e: unknown): e is ElementNotEnabledError {\n  return e instanceof Error && /failed enabled check/.test(e.message);\n}","tryCatchPattern":"try { await humanClick(page, sel); } catch (e) { if (isElementNotEnabledError(e)) { await completePreconditions(); await humanClick(page, sel); } else throw e; }","preventionTips":["Fill all required fields before submitting","Await toBeEnabled() on gated buttons","Treat lingering disabled state as a possible app bug, not test flake"],"tags":["disabled-element","actionability","form","playwright"],"backgroundTag":"element-disabled","analyzedSha":"d6bad5de261bedf025280ace1d14e800aee13923","analyzedAt":"2026-08-28T14:13:12.918Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}