jackwener/OpenCLI · error · Error

${errMsg}

Error message

${errMsg}

What it means

cdp.evaluate ran a Runtime.evaluate expression that produced an uncaught JS exception in the page; the library rethrows the exception's description (or the CDP text) verbatim to the caller. This is the page's own error, not a transport failure — detached/target-closed messages get special handling, everything else is surfaced as-is.

Source

Thrown at extension/src/cdp.ts:254

  // attach retries; a debugger error mid-evaluate invalidates the attach
  // cache so the next attempt re-attaches.
  try {
    await ensureAttached(tabId, aggressiveRetry);

    const result = await sendDebuggerCommand({ tabId }, 'Runtime.evaluate', {
      expression,
      returnByValue: true,
      awaitPromise: true,
    }, timeoutMs) as {
      result?: { type: string; value?: unknown; description?: string; subtype?: string };
      exceptionDetails?: { exception?: { description?: string }; text?: string };
    };

    if (result.exceptionDetails) {
      const errMsg = result.exceptionDetails.exception?.description
        || result.exceptionDetails.text
        || 'Eval error';
      throw new Error(errMsg);
    }

    return result.result?.value;
  } catch (e) {
    const msg = e instanceof Error ? e.message : String(e);
    if (msg.includes('Detached') || msg.includes('Debugger is not attached') || msg.includes('Target closed')) {
      attached.delete(tabId); // Force re-attach on the next command
    }
    throw e;
  }
}

export const evaluateAsync = evaluate;

/**
 * Capture a screenshot via CDP Page.captureScreenshot.
 * Returns base64-encoded image data.
 */

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Fix the evaluated JavaScript — null-check objects before dereferencing
  2. Wrap the expression in try/catch inside the page and return a diagnostic value
  3. Ensure the page is fully loaded before evaluating (wait for load/DOMContentLoaded)
  4. Validate that globals/APIs the expression relies on still exist in the current page bundle

Example fix

// before
await cdp.evaluate(tabId, 'document.querySelector(".a").textContent')
// after
await cdp.evaluate(tabId, 'document.querySelector(".a")?.textContent ?? null')
Defensive patterns

Strategy: try-catch

Validate before calling

const probe = await cdp.evaluate(tabId, `(typeof document !== 'undefined')`);
if (probe !== true) throw new Error('page not ready for evaluation');

Type guard

function isPageScriptError(e: unknown): e is Error & { pageException: true } {
  const m = e instanceof Error ? e.message : String(e);
  return !/Detached|not attached|Target closed/.test(m);
}

Try / catch

try {
  return await cdp.evaluate(tabId, expr);
} catch (e) {
  const msg = e instanceof Error ? e.message : String(e);
  if (/Detached|not attached|Target closed/.test(msg)) return reattachAndRetry();
  console.error('page threw:', msg);   // genuine page exception
  throw e;
}

Prevention

When it happens

Trigger: Runtime.evaluate returns result.exceptionDetails because the evaluated expression threw — e.g. calling a method on undefined, a SyntaxError in the expression, or an unhandled promise rejection with returnByValue/awaitPromise enabled.

Common situations: Selector returned null and the expression dereferences it; page CSP or bundles change global names; typos in evaluated JS; evaluating before the page finished loading so expected globals don't exist yet.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/d41975a1de104e76. Report an issue: GitHub.