Bug: evaluate hides JavaScript exception details behind "Uncaught"
Browser Use Version
0.13.10; upstream commit 2b1f9d377999a59fe7627c1a5aa88c12aa42e11f
Bug Description, Steps to Reproduce, Screenshots
The evaluate action discards the useful part of Chromium's JavaScript exception and returns only JavaScript execution error: Uncaught. This is reproducible with a direct tool call on about:blank; no LLM, credentials, iframe, or external website is needed.
For example, return 42; is invalid at the top level. Chromium reports SyntaxError: Illegal return statement, but the action reads only exceptionDetails.text and drops exceptionDetails.exception.description and the location.
Steps and observed behavior
- Run the Python reproducer below against the specified upstream commit.
- Compare
ActionResult.errorwith the raw CDP exception from the same expression. - The action reports only
Uncaught, while CDP identifies the syntax error.
Expected behavior and impact
Return the browser's exception type/message and available line/column through the existing ActionResult.error path. The same information loss affects runtime errors and rejected promises. Losing this diagnostic makes agent recovery and human debugging harder: the caller cannot distinguish malformed JavaScript from a missing variable or a page access error.
The failing script should still fail normally. This report concerns error feedback; it does not request automatic wrapping or re-execution of JavaScript.
Related: #3620 previously showed the generic Uncaught symptom in a quote-rewriting issue. #5277 addresses source rewriting, while this report concerns the exception details lost after CDP returns. I have a focused fix with real Chromium regression coverage.
Failing Python Code
import asyncio
from browser_use.browser import BrowserProfile, BrowserSession
from browser_use.tools.service import Tools
async def main():
browser = BrowserSession(
browser_profile=BrowserProfile(
headless=True,
user_data_dir=None,
use_cloud=False,
enable_default_extensions=False,
)
)
await browser.start()
try:
await browser.navigate_to('about:blank')
result = await Tools().registry.execute_action(
'evaluate', {'code': 'return 42;'}, browser_session=browser
)
print('ACTION_RESULT:', result.error)
cdp = await browser.get_or_create_cdp_session()
raw = await cdp.cdp_client.send.Runtime.evaluate(
params={
'expression': 'return 42;',
'returnByValue': True,
'awaitPromise': True,
},
session_id=cdp.session_id,
)
print('CDP_EXCEPTION:', raw['exceptionDetails']['exception']['description'])
finally:
await browser.kill()
await browser.event_bus.stop(clear=True, timeout=5)
asyncio.run(main())
LLM Model
None. Reproduced through Tools.registry.execute_action without an Agent or LLM.
Operating System & Browser Versions
Windows x64, CPython 3.12.13, local headless Chrome/152.0.7977.83 (CDP protocol 1.3).
Full DEBUG Log Output
Relevant output from the minimal reproducer:
ACTION_RESULT: JavaScript Execution Failed:
JavaScript execution error: Uncaught
Validated Code (after quote fixing):
return 42;
CDP_EXCEPTION: SyntaxError: Illegal return statement
Source: browser-use/browser-use