CherryHQ/cherry-studio · warning · Error

Unknown script error

Error message

Unknown script error

What it means

Returned when a CDP Runtime.evaluate call has exceptionDetails but exceptionDetails.exception?.description is absent/falsy, so there is no descriptive message to surface. The code falls back to the literal string 'Unknown script error'. This is a defensive default for malformed or terse CDP exception payloads.

Source

Thrown at src/main/ai/mcp/servers/browser/controller.ts:716

      expression: code,
      awaitPromise: true,
      returnByValue: true
    })

    try {
      const result = await Promise.race([
        evalPromise,
        new Promise((_, reject) => {
          timeoutHandle = setTimeout(() => reject(new Error('Execution timed out')), timeout)
        })
      ])

      const evalResult = result

      if (evalResult?.exceptionDetails) {
        const message = evalResult.exceptionDetails.exception?.description || 'Unknown script error'
        logger.warn('Runtime.evaluate raised exception', { message })
        throw new Error(message)
      }

      const value = evalResult?.result?.value ?? evalResult?.result?.description ?? null
      return value
    } finally {
      if (timeoutHandle) clearTimeout(timeoutHandle)
    }
  }

  public async reset(privateMode?: boolean, tabId?: string) {
    if (privateMode !== undefined && tabId) {
      const windowKey = this.getWindowKey(privateMode)
      const windowInfo = this.windows.get(windowKey)
      if (windowInfo) {
        this.closeTabInternal(windowInfo, tabId)
        windowInfo.tabs.delete(tabId)

        // If no tabs left, close the window

View on GitHub (pinned to 726446b54c)

Solutions

  1. Inspect the full evalResult.exceptionDetails object (text, exception.type, exception.value, stackTrace) rather than only exception.description.
  2. Simplify the expression and run a trivial probe (e.g. 1+1) to confirm the page is evaluable at all.
  3. Check page CSP headers and contextIsolation/sandbox settings that may strip exception detail.
  4. Wrap the evaluated expression in try/catch on the page so it returns a structured error instead of throwing.

Example fix

// before
const message = evalResult.exceptionDetails.exception?.description || 'Unknown script error'
logger.warn('Runtime.evaluate raised exception', { message })
throw new Error(message)

// after — extract the richest available detail
const d = evalResult.exceptionDetails
const message =
  d.exception?.description ||
  d.text ||
  (d.exception ? `${d.exception.type}: ${JSON.stringify(d.exception.value)}` : null) ||
  'Unknown script error'
logger.warn('Runtime.evaluate raised exception', { message, details: d })
throw new Error(message)
Defensive patterns

Strategy: try-catch

Validate before calling

// Probe eval viability before running the real expression
async function canEvaluate(controller, tabId) {
  try {
    const probe = await controller.eval(tabId, '1+1')
    return probe === 2 || probe === '2'
  } catch {
    return false
  }
}

Try / catch

// Extract the richest available CDP exception detail
function describeEvalError(evalResult) {
  const d = evalResult?.exceptionDetails
  if (!d) return null
  return d.exception?.description || d.text || (d.exception ? `${d.exception.type}: ${JSON.stringify(d.exception.value)}` : null) || 'Unknown script error'
}

Prevention

When it happens

Trigger: Executing JavaScript in a browser tab via the eval tool where the page-side script throws, but the CDP exception object lacks a description field — e.g. a thrown non-Error value, a security/csp rejection, or a detached target.

Common situations: Page CSP blocks evaluation; script throws a primitive (throw 'x') that has no Error.description; the target navigated or was destroyed mid-eval producing a bare exceptionDetails; sandbox context isolation rejecting the expression.

Related errors


AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12). Data as JSON: /api/errors/340ab569cf4e89d4. Report an issue: GitHub.