{"record":{"id":"e61cc778e4ef9d44","repo":"CloakHQ/CloakBrowser","slug":"cloakbrowser-pro-license-could-not-be-validated","errorCode":null,"errorMessage":"CloakBrowser Pro: license could not be validated (server unreachable and no cached validation). Retry in a moment, or unset CLOAKBROWSER_LICENSE_KEY to use the free binary.","messagePattern":"CloakBrowser Pro: license could not be validated \\(server unreachable and no cached validation\\)\\. Retry in a moment, or unset CLOAKBROWSER_LICENSE_KEY to use the free binary\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"js/src/download.ts","lineNumber":137,"sourceCode":"        if (e instanceof BinaryVerificationError) throw e;\n        // Transient failure with no cached Pro binary to use — surface a clear\n        // error rather than silently downloading the free binary.\n        throw new Error(\n          `Pro binary unavailable: ${e}. Your license is valid but the Pro ` +\n            `binary could not be downloaded right now. Retry in a moment. To use ` +\n            `the free binary instead, unset CLOAKBROWSER_LICENSE_KEY.`,\n          { cause: e }\n        );\n      }\n    } else if (info) {\n      // Key supplied but rejected — abort, never downgrade to free.\n      throw new Error(\n        `CloakBrowser Pro: license key is invalid or expired (plan=${info.plan}). ` +\n          `Check CLOAKBROWSER_LICENSE_KEY, or unset it to use the free binary.`,\n      );\n    } else {\n      // Key supplied but unvalidatable (server down, no cache) — abort.\n      throw new Error(\n        \"CloakBrowser Pro: license could not be validated (server unreachable \" +\n          \"and no cached validation). Retry in a moment, or unset \" +\n          \"CLOAKBROWSER_LICENSE_KEY to use the free binary.\",\n      );\n    }\n  }\n\n  // Fail fast if no binary available for this platform\n  checkPlatformAvailable();\n\n  if (requestedVersion) {\n    const binaryPath = getBinaryPath(requestedVersion);\n    if (fs.existsSync(binaryPath) && isExecutable(binaryPath)) {\n      showWelcome();\n      return binaryPath;\n    }\n\n    console.log(","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/CloakHQ/CloakBrowser/blob/d6bad5de261bedf025280ace1d14e800aee13923/js/src/download.ts#L119-L155","documentation":"StealthWorldUnavailableError raised in _get_element_box_async (scroll_async.py:31) when page._stealth_world is None. The async humanization pipeline reads element geometry exclusively through the isolated world (no Playwright bounding_box fallback), so a missing world makes any async box read fail immediately.","triggerScenarios":"Calling async helpers (_get_element_box_async via _get) on a page created without stealth attach — plain browser.new_page(), a context where stealth was disabled, or after the world was torn down with the context.","commonSituations":"Using async cloakbrowser APIs on pages from a non-stealth launcher; mixing sync-created pages into async flows; accessing a page after browser.close(); version changes in how/when _stealth_world is attached.","solutions":["Create the page through the stealth async launcher so _stealth_world is set before any humanized call.","Check getattr(page, '_stealth_world', None) is not None before async element reads; recreate/re-attach if missing.","Do not reuse page objects after their browser context has been closed."],"exampleFix":"// before\npage = await browser.new_page()  # no stealth world\nbox = await _get_element_box_async(page, sel)\n\n// after\npage = await stealth_context.new_page()  # _stealth_world attached\nbox = await _get_element_box_async(page, sel)","handlingStrategy":"validation","validationCode":"if getattr(page, \"_stealth_world\", None) is None:\n    raise RuntimeError(\"create page via stealth launcher before async humanize calls\")","typeGuard":"def has_stealth_world(page) -> bool:\n    return getattr(page, \"_stealth_world\", None) is not None","tryCatchPattern":"try:\n    box = await _get_element_box_async(page, sel)\nexcept StealthWorldUnavailableError:\n    page = await stealth_context.new_page()\n    box = await _get_element_box_async(page, sel)","preventionTips":["Create all pages through the stealth async launcher","Never reuse page objects after context close","Keep sync and async page creation paths consistent"],"tags":["async","stealth","isolated-world","element-box"],"backgroundTag":"missing-required-context","analyzedSha":"d6bad5de261bedf025280ace1d14e800aee13923","analyzedAt":"2026-08-28T14:13:12.918Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}