CloakHQ/CloakBrowser · error · Error

Pro binary unavailable: ${e}. Your license is valid but the

Error message

Pro binary unavailable: ${e}. Your license is valid but the Pro binary could not be downloaded right now. Retry in a moment. To use the free binary instead, unset CLOAKBROWSER_LICENSE_KEY.

What it means

RuntimeError('Element not found while scrolling into view') is raised when the element's bounding box (obtained via the caller-supplied get_box callback) is None at the start of human_scroll_into_view — the element is detached, hidden (display:none), or never matched, so there is nothing to scroll to.

Source

Thrown at js/src/download.ts:122

      // Paid keys keep pinning/rollback.
      const proVersion = info.plan === "free" ? undefined : requestedVersion;
      // A valid license is entitled to Pro, so Pro failures surface loudly
      // rather than silently substituting the older free binary. (A blip during
      // a routine update never reaches here: ensureProBinary returns the cached
      // Pro binary and updates in the background.)
      try {
        return await ensureProBinary(
          effectiveKey,
          proVersion,
          info.plan,
          releaseChannel,
        );
      } catch (e) {
        // Authenticity could not be confirmed — surface verbatim.
        if (e instanceof BinaryVerificationError) throw e;
        // Transient failure with no cached Pro binary to use — surface a clear
        // error rather than silently downloading the free binary.
        throw new Error(
          `Pro binary unavailable: ${e}. Your license is valid but the Pro ` +
            `binary could not be downloaded right now. Retry in a moment. To use ` +
            `the free binary instead, unset CLOAKBROWSER_LICENSE_KEY.`,
          { cause: e }
        );
      }
    } else if (info) {
      // Key supplied but rejected — abort, never downgrade to free.
      throw new Error(
        `CloakBrowser Pro: license key is invalid or expired (plan=${info.plan}). ` +
          `Check CLOAKBROWSER_LICENSE_KEY, or unset it to use the free binary.`,
      );
    } else {
      // Key supplied but unvalidatable (server down, no cache) — abort.
      throw new Error(
        "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.",

View on GitHub (pinned to d6bad5de26)

Solutions

  1. Wait for the element to be attached/visible first (page.wait_for_selector(sel, state='visible')) before calling human_scroll_into_view.
  2. Verify the selector actually matches: page.query_selector(sel) should not be None; fix shadow-dom/iframe-aware selectors.
  3. If the element may legitimately be display:none, scroll an ancestor container instead or make it visible first.
  4. Re-query the element after mutations instead of holding a stale handle.

Example fix

// before
human_scroll_into_view(page, sel, get_box, cfg)  # element not yet rendered

// after
page.wait_for_selector(sel, state='visible', timeout=5000)
human_scroll_into_view(page, sel, get_box, cfg)
Defensive patterns

Strategy: validation

Validate before calling

if page.query_selector(sel) is None:
    page.wait_for_selector(sel, state='visible', timeout=5000)

Type guard

def element_present(page, sel) -> bool:
    return page.query_selector(sel) is not None

Try / catch

try:
    human_scroll_into_view(page, sel, get_box, cfg)
except RuntimeError as e:
    if 'not found while scrolling' not in str(e): raise
    page.wait_for_selector(sel, state='visible', timeout=5000)
    human_scroll_into_view(page, sel, get_box, cfg)

Prevention

When it happens

Trigger: Passing a selector/locator for an element that does not currently exist (get_box() returns None): element removed by React re-render, display:none container, wrong selector, or SPA route change that destroyed the node before the scroll call.

Common situations: Dynamic SPAs where the node is replaced between query and scroll; selectors that match only after async data loads; shadow-DOM or iframe elements the box reader cannot see; typo'd selectors.

Related errors


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