CloakHQ/CloakBrowser · error · UnsupportedHumanizeSelectorError

UnsupportedHumanizeSelectorError

Error message

UnsupportedHumanizeSelectorError

What it means

The isolated-world DOM evaluator reported StealthStatus.Unsupported for the given selector, meaning the selector's shape is not something the stealth DOM engine can evaluate. The library throws UnsupportedHumanizeSelectorError so callers know to rewrite the selector rather than wait or retry.

Source

Thrown at dotnet/src/CloakBrowser/Human/Actionability.cs:166

        int attempt = 0;
        Exception? lastError = null;

        while (true)
        {
            double remainingMs = Math.Max(0, deadline - NowMs());
            if (remainingMs <= 0)
            {
                if (lastError != null)
                    throw lastError;
                throw new ActionabilityError(selector, "timeout", "timeout expired before first check");
            }

            try
            {
                var (status, snapshot) = await StealthDom.ActionableAsync(
                    stealth, selector).ConfigureAwait(false);
                if (status == StealthStatus.Unsupported)
                    throw new UnsupportedHumanizeSelectorError(selector);
                if (status == StealthStatus.EvaluationFailed)
                    throw new StealthEvaluationError(selector);
                if (status == StealthStatus.NotFound)
                    throw new ElementNotAttachedError(selector);
                if (status != StealthStatus.Ok || snapshot == null)
                    throw new StealthEvaluationError(selector);

                var value = snapshot.Value;
                if (checks.Contains("visible") && !value.Visible)
                    throw new ElementNotVisibleError(selector);
                if (checks.Contains("enabled") && !value.Enabled)
                    throw new ElementNotEnabledError(selector);
                if (checks.Contains("editable") && !value.Editable)
                    throw new ElementNotEditableError(selector);
                return;
            }
            catch (Exception error) when (error is ActionabilityError or StealthEvaluationError)
            {

View on GitHub (pinned to d6bad5de26)

Solutions

  1. Rewrite the selector as simple CSS (tag, id, class, attribute combinators).
  2. Check the library docs for the exact selector grammar StealthDom supports.
  3. Replace XPath with an equivalent CSS selector or resolve the element first and use a stable attribute selector.

Example fix

// before
await Actionability.EnsureActionableAsync(page, "//button[@id='submit']", stealth);

// after
await Actionability.EnsureActionableAsync(page, "button#submit", stealth);
Defensive patterns

Strategy: validation

Validate before calling

static bool IsSupportedSelector(string s) =>
    !s.StartsWith("//") && !s.StartsWith("(") && !s.Contains(":has(") && !s.Contains("::");
if (!IsSupportedSelector(selector)) selector = ToCssSelector(selector); // pre-normalize

Type guard

static bool IsSupportedHumanizeSelector(string selector) =>
    selector.All(c => char.IsLetterOrDigit(c) || " #.>[]:-_@[*=$^~|()'\"".Contains(c)) && !selector.Contains("::");

Try / catch

catch (UnsupportedHumanizeSelectorError ex)
{
    selector = Cssify(ex.Selector); // convert to plain CSS and retry
    await Actionability.EnsureActionableAsync(page, selector, stealth);
}

Prevention

When it happens

Trigger: Calling EnsureActionableAsync/EnsureActionableWorldAsync with a selector type not supported by StealthDom.ActionableAsync — e.g. XPath, pseudo-elements, or complex CSS the evaluator cannot translate — so the first evaluation returns Unsupported.

Common situations: Passing XPath ('//div[@id=...]') where only simple CSS selectors are supported; using pseudo-classes like :has() or :nth-of-type() the evaluator rejects; copy-pasted DevTools selectors; library upgrades narrowing the supported selector grammar.

Related errors


AI-assisted analysis of CloakHQ/CloakBrowser@d6bad5de26 (2026-08-28). Data as JSON: /api/errors/ef7becd662d65f35. Report an issue: GitHub.