CloakHQ/CloakBrowser · error · Error

Download completed but binary not found at expected path: ${

Error message

Download completed but binary not found at expected path: ${downloadedPath}. This may indicate a packaging issue. Please report at https://github.com/CloakHQ/cloakbrowser/issues

What it means

StealthEvaluationError(selector) is raised in _get_element_box_async when the isolated-world evaluate returns a status other than OK/NOT_FOUND/UNSUPPORTED — i.e. the geometry probe itself failed inside the isolated world. The selector string is used as the message so you can identify which probe blew up.

Source

Thrown at js/src/download.ts:199

  // Fall back to platform's hardcoded version if effective version binary doesn't exist
  const platformVersion = getChromiumVersion();
  if (effective !== platformVersion) {
    const fallbackPath = getBinaryPath();
    if (fs.existsSync(fallbackPath) && isExecutable(fallbackPath)) {
      maybeTriggerUpdateCheck();
      return fallbackPath;
    }
  }

  // Download platform's hardcoded version
  console.log(
    `[cloakbrowser] Stealth Chromium ${platformVersion} not found. Downloading for ${getPlatformTag()}...`
  );
  await downloadAndExtract();

  const downloadedPath = getBinaryPath();
  if (!fs.existsSync(downloadedPath)) {
    throw new Error(
      `Download completed but binary not found at expected path: ${downloadedPath}. ` +
      `This may indicate a packaging issue. Please report at ` +
      `https://github.com/CloakHQ/cloakbrowser/issues`
    );
  }

  maybeTriggerUpdateCheck();
  return downloadedPath;
}

/** Remove all cached binaries. Forces re-download on next launch. */
export function clearCache(): void {
  const cacheDir = getCacheDir();
  if (fs.existsSync(cacheDir)) {
    fs.rmSync(cacheDir, { recursive: true, force: true });
    console.log(`[cloakbrowser] Cache cleared: ${cacheDir}`);
  }
}

View on GitHub (pinned to d6bad5de26)

Solutions

  1. Wait for load state / a stable document before the async box read so evaluate stops failing mid-navigation.
  2. Verify the element is not inside a cross-origin iframe — the isolated world cannot measure those; switch to the frame's own page/context first.
  3. Increase the timeout argument so the internal retry loop can outlast transient failures.
  4. Confirm the page/context is still open and _stealth_world is healthy before retrying.

Example fix

// before
box = await _get_element_box_async(page, sel, timeout=100)

// after
await page.wait_for_load_state('domcontentloaded')
box = await _get_element_box_async(page, sel, timeout=5000)
Defensive patterns

Strategy: retry

Validate before calling

if page.is_closed() or getattr(page, "_stealth_world", None) is None:
    raise RuntimeError('page not ready')
await page.wait_for_load_state('domcontentloaded')

Type guard

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

Try / catch

try:
    box = await _get_element_box_async(page, sel, timeout=5000)
except StealthEvaluationError:
    await asyncio.sleep(0.25)
    box = await _get_element_box_async(page, sel, timeout=5000)

Prevention

When it happens

Trigger: async_eval_parsed(world, build_box_js(selector)) returning EVALUATION_FAILED past the retry deadline: page navigating/crashing, isolated world destroyed, or the injected script throwing (e.g. cross-origin restrictions on the element).

Common situations: Element inside a cross-origin iframe; page navigation racing the 50ms polling loop for the whole timeout; CDP session dropped in remote debugging; obfuscated pages tampering with execution contexts.

Related errors


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