{"record":{"id":"0572250b84679985","repo":"browser-use/browser-use","slug":"javascript-code-must-start-with-args-forma","errorCode":null,"errorMessage":"JavaScript code must start with (...args) => format. Got: {page_function[:50]}...","messagePattern":"JavaScript code must start with \\(\\.\\.\\.args\\) => format\\. Got: (.+?)\\.\\.\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"browser_use/actor/page.py","lineNumber":121,"sourceCode":"\tasync def evaluate(self, page_function: str, *args) -> str:\n\t\t\"\"\"Execute JavaScript in the target.\n\n\t\tArgs:\n\t\t\tpage_function: JavaScript code that MUST start with (...args) => format\n\t\t\t*args: Arguments to pass to the function\n\n\t\tReturns:\n\t\t\tString representation of the JavaScript execution result.\n\t\t\tObjects and arrays are JSON-stringified.\n\t\t\"\"\"\n\t\tsession_id = await self._ensure_session()\n\n\t\t# Clean and fix common JavaScript string parsing issues\n\t\tpage_function = self._fix_javascript_string(page_function)\n\n\t\t# Enforce arrow function format\n\t\tif not (page_function.startswith('(') and '=>' in page_function):\n\t\t\traise ValueError(f'JavaScript code must start with (...args) => format. Got: {page_function[:50]}...')\n\n\t\t# Build the expression - call the arrow function with provided args\n\t\tif args:\n\t\t\t# Convert args to JSON representation for safe passing\n\t\t\timport json\n\n\t\t\targ_strs = [json.dumps(arg) for arg in args]\n\t\t\texpression = f'({page_function})({\", \".join(arg_strs)})'\n\t\telse:\n\t\t\texpression = f'({page_function})()'\n\n\t\t# Debug: log the actual expression being evaluated\n\t\tlogger.debug(f'Evaluating JavaScript: {repr(expression)}')\n\n\t\tparams: 'EvaluateParameters' = {'expression': expression, 'returnByValue': True, 'awaitPromise': True}\n\t\tresult = await self._client.send.Runtime.evaluate(\n\t\t\tparams,\n\t\t\tsession_id=session_id,","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/browser-use/browser-use/blob/6c73fced2f6d45a11d88622fe56365a5fe18f28b/browser_use/actor/page.py#L103-L139","documentation":"Raised by ActorPage.evaluate() when the page_function does not begin with '(' or does not contain '=>'. The library only accepts JavaScript written as an arrow function, e.g. '() => document.title', because it wraps the code as '({page_function})()' before sending it to CDP Runtime.evaluate. Any other syntax (bare statements, 'function' declarations, async IIFE) is rejected before execution.","triggerScenarios":"Calling page.evaluate('document.title') or page.evaluate('return 1') (no arrow syntax); passing a statement string like 'window.scrollTo(0, 500)'; passing code that starts with whitespace/quote wrappers that _fix_javascript_string strips so the leading '(' is lost.","commonSituations":"Developers coming from Playwright's page.evaluate which accepts expressions and function bodies; LLM-generated evaluate actions that emit plain JS statements instead of arrow functions; double-quoted strings that get unwrapped and mangled by the cleaning step.","solutions":["Rewrite the code as an arrow function: page.evaluate('() => document.title')","Wrap statements in a zero-arg arrow body: page.evaluate('() => { window.scrollTo(0, 500); return \"done\"; }')","If the string came from an LLM tool call, pre-validate it client-side with a regex like r'^\\\\s*\\\\(.*=>'","Upgrade/check version: newer browser-use releases may auto-wrap non-arrow code in some code paths, but do not rely on it"],"exampleFix":"# before\nawait page.evaluate('document.title')\n\n# after\nawait page.evaluate('() => document.title')","handlingStrategy":"validation","validationCode":"import re\nARROW_RE = re.compile(r'^\\s*\\(.*=>', re.DOTALL)\ndef as_arrow_fn(js: str) -> str:\n    js = js.strip()\n    if not ARROW_RE.match(js):\n        return f'() => {{ {js} }}' if not js.endswith(';') else f'() => {{ {js} }}'\n    return js\n\npage_function = as_arrow_fn(page_function)\nassert page_function.startswith('(') and '=>' in page_function","typeGuard":"def is_arrow_function(code: str) -> bool:\n    code = code.strip()\n    return code.startswith('(') and '=>' in code","tryCatchPattern":"try:\n    await page.evaluate(js)\nexcept ValueError as e:\n    if 'must start with' in str(e):\n        await page.evaluate(f'() => {{ {js} }}')  # one-shot repair\n    else:\n        raise","preventionTips":["Always author evaluate code as '() => ...' from the start","When an LLM generates evaluate actions, validate the arrow format before executing","Prefer a shared helper that normalizes JS to arrow format once"],"tags":["javascript","cdp","evaluate","validation"],"backgroundTag":null,"analyzedSha":"6c73fced2f6d45a11d88622fe56365a5fe18f28b","analyzedAt":"2026-08-14T19:42:40.557Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}