CloakHQ/CloakBrowser · error · UnsupportedHumanizeSelectorError
Humanized selector ${selector} is not supported by the isola
Error message
Humanized selector ${selector} is not supported by the isolated-world resolver. Supported: CSS, text=, xpath=, getByTestId, getByPlaceholder, getByAltText, getByTitle, getByText, getByLabel, and a trailing .first()/.nth()/.last(). Not supported: getByRole, chained locators (a >> b, .filter(), .and(), .or()), frameLocator, :visible and :nth-match. Use a CSS or text= selector for this action, or humanize:false to fall back to Playwright. What it means
readBox's selector resolution reported UNSUPPORTED: the humanized isolated-world resolver only accepts a limited selector grammar (CSS, text=, xpath=, getBy* testid/placeholder/altText/title/text/label with optional trailing .first()/.nth()/.last()). Constructs like getByRole, chained locators (>>, .filter(), .and(), .or()), frameLocator, :visible and :nth-match are rejected.
Source
Thrown at js/src/human/actionability.ts:134
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(
pageOrFrame: Page | Frame,
selector: string,
checks: ReadonlySet<CheckName>,
timeout: number = 30000,
force: boolean = false,
): Promise<void> {
if (force) return;
const deadline = Date.now() + timeout;
let attempt = 0;
let lastError: Error | null = null;
while (true) {
const remainingMs = Math.max(0, deadline - Date.now());View on GitHub (pinned to d6bad5de26)
Solutions
- Replace getByRole with a CSS, text=, or getByTestId selector (e.g. text="Sign in" or [data-testid="sign-in"])
- Unwind chained locators: resolve to a single selector targeting the final element directly
- Drop :visible / :nth-match — the actionability layer already performs visibility checks and .first()/.nth()/.last() are supported
- If the selector cannot be simplified, pass humanize:false so the action uses Playwright's native locator engine
Example fix
// before
await humanClick(page, 'getByRole("button", { name: "Sign in" })');
// after
await humanClick(page, 'text="Sign in"');
// or bypass the isolated world
await page.getByRole('button', { name: 'Sign in' }).click(); Defensive patterns
Strategy: type-guard
Validate before calling
const SUPPORTED = /^(?:[.#]?[\w-]+|text=|xpath=|getBy(TestId|Placeholder|AltText|Title|Text|Label))/;
if (!SUPPORTED.test(sel)) { /* use a native locator instead */ } Type guard
function isUnsupportedHumanizeSelectorError(e: unknown): e is UnsupportedHumanizeSelectorError {
return e instanceof Error && /not supported by the isolated-world resolver/.test(e.message);
} Try / catch
try { await humanClick(page, sel); } catch (e) { if (isUnsupportedHumanizeSelectorError(e)) await page.locator(sel).click(); else throw e; } Prevention
- Standardize on data-testid or text= selectors for humanized actions
- Avoid getByRole and locator chaining in humanized paths
- Reach for humanize:false when rich locators are required
When it happens
Trigger: Passing page.getByRole('button', { name: 'Go' })-style selectors or chained/filtered locator strings to humanized actions (humanClick, humanHover, humanType...) that internally call readBox/stealthActionable.
Common situations: Porting existing Playwright tests that lean on getByRole and .filter() — the two most common unsupported constructs — or using :visible pseudo-selectors copied from CSS-based test suites.
Related errors
- Humanized selector ${selector} is not supported by the isola
- Humanized DOM read requires an active isolated world
- Element not found while scrolling into view
- ElementNotAttachedError: {sourceSelector}
- ElementNotAttachedError: {targetSelector}
AI-assisted analysis of CloakHQ/CloakBrowser@d6bad5de26 (2026-08-28).
Data as JSON: /api/errors/9b7761dc9151a8ae.
Report an issue: GitHub.