CloakHQ/CloakBrowser · error · ElementNotVisibleError
Element ${selector} failed visible check: element is not vis
Error message
Element ${selector} failed visible check: element is not visible What it means
The element was found and evaluated, but with the 'visible' check requested the probe reported data.visible === false (zero size, display:none, visibility:hidden, or hidden ancestor).
Source
Thrown at js/src/human/actionability.ts:119
// ---------------------------------------------------------------------------
// 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);
}
View on GitHub (pinned to d6bad5de26)
Solutions
- Trigger the UI state that reveals the element first (open the dropdown, switch tab, scroll into view)
- Await visibility before acting: expect(locator).toBeVisible() or waitForSelector with state:'visible'
- Increase the action timeout so animation/transition periods are covered
- If acting on a hidden element is intentional, drop 'visible' from the checks set or use native Playwright
Example fix
// before
await humanClick(page, '[data-testid="menu-item-2"]');
// after
await humanClick(page, '[data-testid="menu"]'); // open menu
await page.waitForSelector('[data-testid="menu-item-2"]', { state: 'visible' });
await humanClick(page, '[data-testid="menu-item-2"]'); Defensive patterns
Strategy: validation
Validate before calling
await page.locator(sel).waitFor({ state: 'visible', timeout: 5000 }); Type guard
function isElementNotVisibleError(e: unknown): e is ElementNotVisibleError {
return e instanceof Error && /failed visible check/.test(e.message);
} Try / catch
try { await humanClick(page, sel); } catch (e) { if (isElementNotVisibleError(e)) { await openMenuFirst(); await humanClick(page, sel); } else throw e; } Prevention
- Open the containing UI state (menu/tab) before clicking children
- Await visible state rather than relying on the internal poll
- Account for entrance animations with adequate timeouts
When it happens
Trigger: Calling ensureActionable with 'visible' in checks (default for click/hover/type actions) on an element that is hidden — e.g. a dropdown menu not yet opened, a modal overlay state, or an element mid-animation.
Common situations: Clicking menu items before opening the menu, tabs whose inactive panes are display:none, CSS animations mid-transition, off-screen carousels, or elements hidden by responsive breakpoints in emulated viewports.
Related errors
- Isolated-world DOM evaluation failed for ${selector}
- Element ${selector} failed attached check: element not found
- Element ${selector} failed enabled check: element is disable
- Element not found while scrolling into view
- Invalid browser version pin. Use a full numeric Chromium ver
AI-assisted analysis of CloakHQ/CloakBrowser@d6bad5de26 (2026-08-28).
Data as JSON: /api/errors/1776b4c6fd600724.
Report an issue: GitHub.