CloakHQ/CloakBrowser · error · Error
CLOAKBROWSER_BINARY_PATH set to '${localOverride}' but file
Error message
CLOAKBROWSER_BINARY_PATH set to '${localOverride}' but file does not exist What it means
RuntimeError('Viewport size not available') is raised in human_scroll_into_view when the resolved viewport dict is falsy or lacks a 'height' key — e.g. _VIEWPORT_JS returned an empty/None result, or the caller-supplied viewport was {'width': 0} or None. The scroller cannot compute geometry without a viewport height, so it aborts rather than guess.
Source
Thrown at js/src/download.ts:85
// ---------------------------------------------------------------------------
// Public API
// ---------------------------------------------------------------------------
/**
* Ensure the stealth Chromium binary is available. Download if needed.
* Returns the path to the chrome executable.
*/
export async function ensureBinary(
licenseKey?: string,
browserVersion?: string,
releaseChannel?: string,
): Promise<string> {
// Check for local override
const localOverride = getLocalBinaryOverride();
if (localOverride) {
if (!fs.existsSync(localOverride)) {
throw new Error(
`CLOAKBROWSER_BINARY_PATH set to '${localOverride}' but file does not exist`
);
}
console.log(`[cloakbrowser] Using local binary override: ${localOverride}`);
return localOverride;
}
const requestedVersion = normalizeRequestedVersion(browserVersion);
// Pro license key check (custom download URL overrides Pro path)
const key = resolveLicenseKey(licenseKey);
const effectiveKey = process.env.CLOAKBROWSER_DOWNLOAD_URL ? undefined : key;
if (effectiveKey) {
const info = await validateLicense(effectiveKey);
if (info?.valid) {
// Free tier always gets the latest build. Drop any version pin: the server
// force-serves latest to free keys, so fetching a pinned version's signed
// manifest would mismatch the served bytes and fail checksum verification.View on GitHub (pinned to d6bad5de26)
Solutions
- Wait until the page has laid out (domcontentloaded plus a real document, not about:blank) before scrolling.
- Launch with an explicit viewport so the value comes from Playwright configuration, not runtime reads.
- Debug what _VIEWPORT_JS returns: run page._stealth_world.evaluate(_VIEWPORT_JS) and confirm {'width','height'} are non-zero; if zero, the environment itself lacks a layout viewport.
- Retry once after a short delay for layout races.
Example fix
// before
page.goto('about:blank')
human_scroll_into_view(page, sel, get_box, cfg)
// after
page.goto('https://example.com')
page.wait_for_load_state('domcontentloaded')
human_scroll_into_view(page, sel, get_box, cfg) Defensive patterns
Strategy: validation
Validate before calling
vp = page.viewport_size or (page._stealth_world.evaluate(_VIEWPORT_JS) if getattr(page, '_stealth_world', None) else None)
if not vp or not vp.get('height'):
raise RuntimeError('viewport not measurable; wait for layout') Type guard
def has_viewport(page) -> bool:
vp = page.viewport_size
return bool(vp and vp.get('height')) Try / catch
try:
human_scroll_into_view(page, sel, get_box, cfg)
except RuntimeError as e:
if 'Viewport size not available' not in str(e): raise
page.wait_for_load_state('domcontentloaded')
human_scroll_into_view(page, sel, get_box, cfg) Prevention
- Never scroll on about:blank or pre-layout pages
- Set an explicit viewport at launch
- Avoid embedded webview shells without layout viewports
When it happens
Trigger: world.evaluate(_VIEWPORT_JS) returning None/{} (window.tears down mid-read, unusual embedded webviews), or page.viewport_size returning a dict without height; also passing viewport={} explicitly.
Common situations: Embedded/minimal browser shells (webview, old headless shell) where innerWidth/innerHeight are 0; popup windows opened with window.open before layout; pages in about:blank; races right after navigation where layout is not yet computed.
Related errors
- Viewport size not available
- Viewport size not available
- Invalid browser version pin. Use a full numeric Chromium ver
- Unsupported platform: ${platform} ${arch}. Supported: ${supp
- CloakBrowser — Pre-built binaries are currently only availab
AI-assisted analysis of CloakHQ/CloakBrowser@d6bad5de26 (2026-08-28).
Data as JSON: /api/errors/de19cfead6021221.
Report an issue: GitHub.