{"record":{"id":"99bd4f6b2b90d979","repo":"CloakHQ/CloakBrowser","slug":"invalid-browser-version-pin-use-a-full-numeric-ch","errorCode":null,"errorMessage":"Invalid browser version pin. Use a full numeric Chromium version, e.g. '148.0.7778.215.2'.","messagePattern":"Invalid browser version pin\\. Use a full numeric Chromium version, e\\.g\\. '148\\.0\\.7778\\.215\\.2'\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"js/src/config.ts","lineNumber":81,"sourceCode":"};\n\n// Platforms with pre-built binaries available for download (derived from version map).\nconst AVAILABLE_PLATFORMS = new Set(Object.keys(PLATFORM_CHROMIUM_VERSIONS));\n\nconst VERSION_PIN_RE = /^[0-9]+(?:\\.[0-9]+){3,4}$/;\n\nexport function normalizeReleaseChannel(releaseChannel?: string): \"stable\" | \"preview\" {\n  const raw = releaseChannel ?? process.env.CLOAKBROWSER_RELEASE_CHANNEL ?? \"stable\";\n  return raw.trim().toLowerCase() === \"preview\" ? \"preview\" : \"stable\";\n}\n\nexport function normalizeRequestedVersion(version?: string): string | undefined {\n  const raw = version ?? process.env.CLOAKBROWSER_VERSION;\n  if (raw == null) return undefined;\n  const normalized = raw.trim();\n  if (!normalized) return undefined;\n  if (!VERSION_PIN_RE.test(normalized)) {\n    throw new Error(\n      \"Invalid browser version pin. Use a full numeric Chromium version, \" +\n        \"e.g. '148.0.7778.215.2'.\"\n    );\n  }\n  return normalized;\n}\n\nexport function getChromiumVersion(): string {\n  const tag = getPlatformTag();\n  return PLATFORM_CHROMIUM_VERSIONS[tag] ?? CHROMIUM_VERSION;\n}\n\nexport function getPlatformTag(): string {\n  const platform = process.platform;\n  const arch = process.arch;\n\n  // Map Node.js platform/arch to our tag format\n  let key: string;","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/CloakHQ/CloakBrowser/blob/d6bad5de261bedf025280ace1d14e800aee13923/js/src/config.ts#L63-L99","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure the page is fully loaded and not navigating before scrolling (wait for load_state or a stable selector).","Check page.is_closed() and that the stealth world is attached (page._stealth_world is not None) before calling scroll APIs.","Retry the scroll once after a short delay — transient teardown during navigation is the most common cause.","Upgrade cloakbrowser if the isolated-world binding was flaky in your version."],"exampleFix":"// before\nhuman_scroll_into_view(page, sel, get_box, cfg)\n\n// after\nif page.is_closed() or getattr(page, \"_stealth_world\", None) is None:\n    raise RuntimeError(\"page not ready for stealth scroll\")\ntry:\n    human_scroll_into_view(page, sel, get_box, cfg)\nexcept StealthEvaluationError:\n    page.wait_for_load_state(\"domcontentloaded\")\n    human_scroll_into_view(page, sel, get_box, cfg)","handlingStrategy":"retry","validationCode":"if page.is_closed() or getattr(page, \"_stealth_world\", None) is None:\n    raise RuntimeError(\"page not ready for stealth scroll\")","typeGuard":"def scroll_state_readable(page) -> bool:\n    return (not page.is_closed()) and getattr(page, \"_stealth_world\", None) is not None","tryCatchPattern":"try:\n    human_scroll_into_view(page, sel, get_box, cfg)\nexcept StealthEvaluationError:\n    page.wait_for_load_state(\"domcontentloaded\")\n    human_scroll_into_view(page, sel, get_box, cfg)  # one retry","preventionTips":["Wait for load state before scrolling","Never scroll on a closed page or one without _stealth_world","Avoid scroll calls immediately after navigation-triggering clicks"],"tags":["playwright","stealth","scroll","isolated-world","cdp"],"backgroundTag":"page-evaluation-failed","analyzedSha":"d6bad5de261bedf025280ace1d14e800aee13923","analyzedAt":"2026-08-28T14:13:12.918Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}