{"record":{"id":"340ab569cf4e89d4","repo":"CherryHQ/cherry-studio","slug":"unknown-script-error","errorCode":null,"errorMessage":"Unknown script error","messagePattern":"Unknown script error","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/main/ai/mcp/servers/browser/controller.ts","lineNumber":716,"sourceCode":"      expression: code,\n      awaitPromise: true,\n      returnByValue: true\n    })\n\n    try {\n      const result = await Promise.race([\n        evalPromise,\n        new Promise((_, reject) => {\n          timeoutHandle = setTimeout(() => reject(new Error('Execution timed out')), timeout)\n        })\n      ])\n\n      const evalResult = result\n\n      if (evalResult?.exceptionDetails) {\n        const message = evalResult.exceptionDetails.exception?.description || 'Unknown script error'\n        logger.warn('Runtime.evaluate raised exception', { message })\n        throw new Error(message)\n      }\n\n      const value = evalResult?.result?.value ?? evalResult?.result?.description ?? null\n      return value\n    } finally {\n      if (timeoutHandle) clearTimeout(timeoutHandle)\n    }\n  }\n\n  public async reset(privateMode?: boolean, tabId?: string) {\n    if (privateMode !== undefined && tabId) {\n      const windowKey = this.getWindowKey(privateMode)\n      const windowInfo = this.windows.get(windowKey)\n      if (windowInfo) {\n        this.closeTabInternal(windowInfo, tabId)\n        windowInfo.tabs.delete(tabId)\n\n        // If no tabs left, close the window","sourceCodeStart":698,"sourceCodeEnd":734,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/src/main/ai/mcp/servers/browser/controller.ts#L698-L734","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the full evalResult.exceptionDetails object (text, exception.type, exception.value, stackTrace) rather than only exception.description.","Simplify the expression and run a trivial probe (e.g. 1+1) to confirm the page is evaluable at all.","Check page CSP headers and contextIsolation/sandbox settings that may strip exception detail.","Wrap the evaluated expression in try/catch on the page so it returns a structured error instead of throwing."],"exampleFix":"// before\nconst message = evalResult.exceptionDetails.exception?.description || 'Unknown script error'\nlogger.warn('Runtime.evaluate raised exception', { message })\nthrow new Error(message)\n\n// after — extract the richest available detail\nconst d = evalResult.exceptionDetails\nconst message =\n  d.exception?.description ||\n  d.text ||\n  (d.exception ? `${d.exception.type}: ${JSON.stringify(d.exception.value)}` : null) ||\n  'Unknown script error'\nlogger.warn('Runtime.evaluate raised exception', { message, details: d })\nthrow new Error(message)","handlingStrategy":"try-catch","validationCode":"// Probe eval viability before running the real expression\nasync function canEvaluate(controller, tabId) {\n  try {\n    const probe = await controller.eval(tabId, '1+1')\n    return probe === 2 || probe === '2'\n  } catch {\n    return false\n  }\n}","typeGuard":null,"tryCatchPattern":"// Extract the richest available CDP exception detail\nfunction describeEvalError(evalResult) {\n  const d = evalResult?.exceptionDetails\n  if (!d) return null\n  return d.exception?.description || d.text || (d.exception ? `${d.exception.type}: ${JSON.stringify(d.exception.value)}` : null) || 'Unknown script error'\n}","preventionTips":["Wrap evaluated page-side expressions in try/catch returning structured errors.","Check CSP and contextIsolation before relying on eval detail.","Log the full exceptionDetails object, not just description."],"tags":["browser-tool","cdp","debug","eval"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}