CloakHQ/CloakBrowser · error · ElementNotEnabledError
Element ${selector} failed enabled check: element is disable
Error message
Element ${selector} failed enabled check: element is disabled What it means
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).
Source
Thrown at js/src/human/actionability.ts:120
// ---------------------------------------------------------------------------
// Pre-scroll actionability
// ---------------------------------------------------------------------------
async function stealthActionable(
pageOrFrame: Page | Frame,
selector: string,
checks: ReadonlySet<CheckName>,
): Promise<void> {
const world = getWorld(pageOrFrame);
if (!world) throw new StealthWorldUnavailableError();
const { status, data } = await evalParsed(world, buildActionableJs(selector));
if (status === UNSUPPORTED) throw new UnsupportedHumanizeSelectorError(selector);
if (status === EVALUATION_FAILED) throw new StealthEvaluationError(selector);
if (status === NOT_FOUND) throw new ElementNotAttachedError(selector);
if (status !== OK || !data) throw new StealthEvaluationError(selector);
if (checks.has('visible') && !data.visible) throw new ElementNotVisibleError(selector);
if (checks.has('enabled') && !data.enabled) throw new ElementNotEnabledError(selector);
if (checks.has('editable') && !data.editable) throw new ElementNotEditableError(selector);
}
async function readBox(
pageOrFrame: Page | Frame,
selector: string,
): Promise<{ x: number; y: number; width: number; height: number } | null> {
const world = getWorld(pageOrFrame);
if (!world) throw new StealthWorldUnavailableError();
const { status, data } = await evalParsed(world, buildBoxJs(selector));
if (status === OK && data?.box) return data.box;
if (status === NOT_FOUND) return null;
if (status === UNSUPPORTED) throw new UnsupportedHumanizeSelectorError(selector);
throw new StealthEvaluationError(selector);
}
export async function ensureActionable(View on GitHub (pinned to d6bad5de26)
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
Example fix
// before
await humanClick(page, '#submit');
// after
await humanFill(page, '#email', 'a@b.c');
await humanFill(page, '#password', 'secret');
await page.waitForFunction(() => !(document.querySelector('#submit') as HTMLButtonElement).disabled);
await humanClick(page, '#submit'); Defensive patterns
Strategy: retry
Validate before calling
await page.waitForFunction((s) => { const el = document.querySelector(s); return !!el && !(el as HTMLButtonElement).disabled; }, sel, { timeout: 5000 }); Type guard
function isElementNotEnabledError(e: unknown): e is ElementNotEnabledError {
return e instanceof Error && /failed enabled check/.test(e.message);
} Try / catch
try { await humanClick(page, sel); } catch (e) { if (isElementNotEnabledError(e)) { await completePreconditions(); await humanClick(page, sel); } else throw e; } Prevention
- Fill all required fields before submitting
- Await toBeEnabled() on gated buttons
- Treat lingering disabled state as a possible app bug, not test flake
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Isolated-world DOM evaluation failed for ${selector}
- Element ${selector} failed visible check: element is not vis
- Element ${selector} failed editable check: element is not ed
- Invalid browser version pin. Use a full numeric Chromium ver
- Element ${selector} failed attached check: element not found
AI-assisted analysis of CloakHQ/CloakBrowser@d6bad5de26 (2026-08-28).
Data as JSON: /api/errors/1f451d4b256d7aec.
Report an issue: GitHub.