{"record":{"id":"eb8cb508fa0cab82","repo":"CloakHQ/CloakBrowser","slug":"pro-download-completed-but-binary-not-found-at","errorCode":null,"errorMessage":"Pro download completed but binary not found at: ${getBinaryPath(latest, true)}","messagePattern":"Pro download completed but binary not found at: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"js/src/download.ts","lineNumber":295,"sourceCode":" */\nexport async function checkForProUpdate(\n  licenseKey: string,\n  releaseChannel?: string,\n): Promise<string | null> {\n  const latest = await getProLatestVersion(releaseChannel);\n  if (!latest) return null;\n\n  const effective = getEffectiveVersion(true, releaseChannel);\n  if (effective && !versionNewer(latest, effective) && proBinaryReady(effective)) {\n    // Already on the latest cached Pro build.\n    return null;\n  }\n\n  if (!proBinaryReady(latest)) {\n    console.log(`[cloakbrowser] Downloading Pro Chromium ${latest}...`);\n    await downloadProBinary(latest, licenseKey);\n    if (!fs.existsSync(getBinaryPath(latest, true))) {\n      throw new Error(\n        `Pro download completed but binary not found at: ${getBinaryPath(latest, true)}`\n      );\n    }\n  }\n\n  writeProVersionMarker(latest, releaseChannel);\n  return latest;\n}\n\n// ---------------------------------------------------------------------------\n// Welcome message (shown once per install)\n// ---------------------------------------------------------------------------\n\n/**\n * Whether the welcome banner should be shown now. Pro: once ever (only when\n * the marker is absent). Free: re-show when the marker is absent or its\n * timestamp is older than WELCOME_FREE_INTERVAL_MS. Unreadable or legacy empty\n * markers count as stale (due).","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/CloakHQ/CloakBrowser/blob/d6bad5de261bedf025280ace1d14e800aee13923/js/src/download.ts#L277-L313","documentation":"StealthEvaluationError('<scroll-state>') raised by _async_read_scroll_state (scroll_async.py:53) when reading scrollY/scrollHeight/innerHeight through the isolated world either throws or returns a non-dict. It is the async twin of the sync scroll-state read and, like it, has no main-world fallback by design.","triggerScenarios":"Calling async_human_scroll_into_view while the page is navigating or closing, or when the isolated world was torn down, so world.evaluate(_SCROLL_JS) raises or returns undefined instead of a dict.","commonSituations":"Async flows that click and immediately scroll (navigation races); awaiting scroll after task cancellation starved the event loop and the CDP session timed out; remote browser connection drops mid-scroll; pages that destroy execution contexts aggressively.","solutions":["Await page.wait_for_load_state(...) before async_human_scroll_into_view so the evaluate does not race navigation.","Guard with page.is_closed() and a not-None _stealth_world check before the call.","Retry the scroll once after asyncio.sleep(0.25) — transient teardown during navigation is the dominant cause.","Check the remote/CDP connection health if failures are persistent."],"exampleFix":"// before\nawait async_human_scroll_into_view(page, sel, get_box, cfg)\n\n// after\nawait page.wait_for_load_state('domcontentloaded')\ntry:\n    await async_human_scroll_into_view(page, sel, get_box, cfg)\nexcept StealthEvaluationError:\n    await asyncio.sleep(0.25)\n    await async_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 async stealth scroll')\nawait page.wait_for_load_state('domcontentloaded')","typeGuard":"def async_scroll_ready(page) -> bool:\n    return (not page.is_closed()) and getattr(page, \"_stealth_world\", None) is not None","tryCatchPattern":"try:\n    await async_human_scroll_into_view(page, sel, get_box, cfg)\nexcept StealthEvaluationError:\n    await asyncio.sleep(0.25)\n    await async_human_scroll_into_view(page, sel, get_box, cfg)","preventionTips":["Await load state before async scrolls","Never scroll a page without an attached stealth world","Shield concurrent tasks so the CDP session isn't starved"],"tags":["async","stealth","scroll","isolated-world"],"backgroundTag":"page-evaluation-failed","analyzedSha":"d6bad5de261bedf025280ace1d14e800aee13923","analyzedAt":"2026-08-28T14:13:12.918Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}