stablyai/orca · error · BrowserError

browser_eval_error

browser_eval_error

Error message

${exceptionDetails.exception?.description ?? exceptionDetails.text}

What it means

Runtime.evaluate returns an exceptionDetails object (rather than rejecting the promise) when the evaluated JavaScript expression throws at runtime. The error message is the exception's description (which includes the V8 stack trace) or falls back to the generic text field. This is distinct from a CDP protocol error: the expression was delivered and executed successfully, but it threw a JS exception. After the throw, the second location.origin eval is not reached.

Source

Thrown at src/main/browser/cdp-bridge.ts:937

    })
  }

  async evaluate(expression: string): Promise<BrowserEvalResult> {
    return this.enqueueCommand(async () => {
      const guest = this.getActiveGuest()
      const sender = this.makeCdpSender(guest)
      await this.ensureDebuggerAttached(guest)

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

      if (exceptionDetails) {
        throw new BrowserError(
          'browser_eval_error',
          exceptionDetails.exception?.description ?? exceptionDetails.text
        )
      }

      const valueStr =
        result.value !== undefined ? String(result.value) : (result.description ?? '')
      // Why: include origin to match agent-browser's BrowserEvalResult shape across both bridges.
      const { result: urlResult } = (await sender('Runtime.evaluate', {
        expression: 'location.origin',
        returnByValue: true
      })) as { result: { value: string } }
      return {
        result: valueStr,
        origin: urlResult.value
      }
    })
  }

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Validate expression syntax before sending (e.g., new Function(expr) in a try-catch on the caller side).
  2. Wrap the expression body in try-catch inside the eval to return a structured error instead of throwing.
  3. Inspect the description field for the actual JS error message and stack trace to debug the expression.

Example fix

// before
await bridge.evaluate('JSON.parse(badJson)')

// after
await bridge.evaluate(`
  (() => {
    try { return JSON.parse(badJson) }
    catch (e) { return { __error: e.message } }
  })()
`)
Defensive patterns

Strategy: try-catch

Validate before calling

function validateEvalSyntax(expr: string): void {
  try {
    new Function(expr)
  } catch (e) {
    throw new Error(`Eval expression has a syntax error: ${(e as Error).message}`)
  }
}
validateEvalSyntax(expression)
await bridge.evaluate(expression)

Try / catch

try {
  return await bridge.evaluate(expression)
} catch (e) {
  if (e instanceof BrowserError && e.code === 'browser_eval_error') {
    // e.message contains the JS exception description + stack
    // wrap future evals in try-catch inside the expression
  }
  throw e
}

Prevention

When it happens

Trigger: Calling evaluate(expression) with a syntax error, a reference to an undefined variable, a function call that throws, or any runtime JS exception (e.g., JSON.parse on invalid input, property access on null).

Common situations: Typo in the eval expression; referencing page globals that don't exist yet; calling functions with side effects that throw; type mismatches in the evaluated code.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/041e5a73c8f74f5a. Report an issue: GitHub.