CloakHQ/CloakBrowser · error · ElementNotAttachedError
Element ${selector} failed attached check: element not found
Error message
Element ${selector} failed attached check: element not found in DOM What it means
The actionability probe resolved the selector in the isolated world and got status NOT_FOUND: no element matched the selector at check time. This is the humanized equivalent of Playwright's 'element not attached / not found' failure.
Source
Thrown at js/src/human/actionability.ts:117
return new Promise(resolve => setTimeout(resolve, BACKOFF_MS[idx]));
}
// ---------------------------------------------------------------------------
// 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
- Wait for the element to exist before the action (waitForSelector / expect(locator).toBeAttached())
- Make the selector resilient: prefer stable data-testid or text= selectors over generated CSS paths
- If the element genuinely may be absent, catch ElementNotAttachedError and treat it as an expected branch
- Verify you are querying the right frame (iframe content needs the Frame object, not the parent Page)
Example fix
// before
await humanClick(page, '#row-42 .btn');
// after
await page.waitForSelector('[data-testid="submit"]');
await humanClick(page, '[data-testid="submit"]'); Defensive patterns
Strategy: validation
Validate before calling
if ((await page.locator(sel).count()) === 0) await page.waitForSelector(sel, { timeout: 5000 }); Type guard
function isElementNotAttachedError(e: unknown): e is ElementNotAttachedError {
return e instanceof Error && /failed attached check/.test(e.message);
} Try / catch
try { await humanClick(page, sel); } catch (e) { if (isElementNotAttachedError(e)) return; /* optional flow */ throw e; } Prevention
- Always waitForSelector before humanized actions
- Prefer stable data-testid selectors
- Scope selectors to the correct frame
When it happens
Trigger: ensureActionable with any check set (visible/enabled/editable) on a selector whose resolver returns NOT_FOUND — element removed from DOM, typo'd selector, or SPA re-render that swapped nodes between discovery and the probe.
Common situations: Selectors that break after re-renders (data-testid churn), acting before the element mounts, detached nodes after route change, or unsupported selector syntax silently resolving to nothing.
Related errors
- Pro binary unavailable: ${e}. Your license is valid but the
- Element ${selector} failed visible check: element is not vis
- CloakBrowser Pro: license key is invalid or expired (plan=${
- Pinned download completed but binary not found at expected p
- Isolated-world DOM evaluation failed for ${selector}
AI-assisted analysis of CloakHQ/CloakBrowser@d6bad5de26 (2026-08-28).
Data as JSON: /api/errors/9db9fb5f5b8d995a.
Report an issue: GitHub.