CloakHQ/CloakBrowser · error · Error

Invalid browser version pin. Use a full numeric Chromium ver

Error message

Invalid browser version pin. Use a full numeric Chromium version, e.g. '148.0.7778.215.2'.

What it means

StealthEvaluationError('<scroll-state>') is raised by _read_scroll_state in cloakbrowser/human/scroll.py when reading the page's vertical scroll position (scrollY, scrollHeight, innerHeight) through the isolated stealth world either throws or returns a non-dict. The library refuses to fall back to the main-world evaluate because that would touch detectable page APIs. It usually means the isolated world was torn down or the page navigated mid-read.

Source

Thrown at js/src/config.ts:81

};

// Platforms with pre-built binaries available for download (derived from version map).
const AVAILABLE_PLATFORMS = new Set(Object.keys(PLATFORM_CHROMIUM_VERSIONS));

const VERSION_PIN_RE = /^[0-9]+(?:\.[0-9]+){3,4}$/;

export function normalizeReleaseChannel(releaseChannel?: string): "stable" | "preview" {
  const raw = releaseChannel ?? process.env.CLOAKBROWSER_RELEASE_CHANNEL ?? "stable";
  return raw.trim().toLowerCase() === "preview" ? "preview" : "stable";
}

export function normalizeRequestedVersion(version?: string): string | undefined {
  const raw = version ?? process.env.CLOAKBROWSER_VERSION;
  if (raw == null) return undefined;
  const normalized = raw.trim();
  if (!normalized) return undefined;
  if (!VERSION_PIN_RE.test(normalized)) {
    throw new Error(
      "Invalid browser version pin. Use a full numeric Chromium version, " +
        "e.g. '148.0.7778.215.2'."
    );
  }
  return normalized;
}

export function getChromiumVersion(): string {
  const tag = getPlatformTag();
  return PLATFORM_CHROMIUM_VERSIONS[tag] ?? CHROMIUM_VERSION;
}

export function getPlatformTag(): string {
  const platform = process.platform;
  const arch = process.arch;

  // Map Node.js platform/arch to our tag format
  let key: string;

View on GitHub (pinned to d6bad5de26)

Solutions

  1. Ensure the page is fully loaded and not navigating before scrolling (wait for load_state or a stable selector).
  2. Check page.is_closed() and that the stealth world is attached (page._stealth_world is not None) before calling scroll APIs.
  3. Retry the scroll once after a short delay — transient teardown during navigation is the most common cause.
  4. Upgrade cloakbrowser if the isolated-world binding was flaky in your version.

Example fix

// before
human_scroll_into_view(page, sel, get_box, cfg)

// after
if page.is_closed() or getattr(page, "_stealth_world", None) is None:
    raise RuntimeError("page not ready for stealth scroll")
try:
    human_scroll_into_view(page, sel, get_box, cfg)
except StealthEvaluationError:
    page.wait_for_load_state("domcontentloaded")
    human_scroll_into_view(page, sel, get_box, cfg)
Defensive patterns

Strategy: retry

Validate before calling

if page.is_closed() or getattr(page, "_stealth_world", None) is None:
    raise RuntimeError("page not ready for stealth scroll")

Type guard

def scroll_state_readable(page) -> bool:
    return (not page.is_closed()) and getattr(page, "_stealth_world", None) is not None

Try / catch

try:
    human_scroll_into_view(page, sel, get_box, cfg)
except StealthEvaluationError:
    page.wait_for_load_state("domcontentloaded")
    human_scroll_into_view(page, sel, get_box, cfg)  # one retry

Prevention

When it happens

Trigger: Calling human_scroll_into_view (directly or via scroll_to_element / _humanized_scroll_into_view_if_needed / _move_to_element) while the page is navigating, closing, or crashing; the CDP isolated-world session is destroyed so world.evaluate(_SCROLL_JS) raises, or returns undefined/null instead of a dict.

Common situations: Scrolling right after a click that triggers navigation; page.close() racing a scroll; target process crash; using a Playwright Page handle after context teardown; headless shell where the isolated world binding is missing in an older version.

Related errors


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