{"record":{"id":"0a257c3bb625887d","repo":"ruvnet/ruflo","slug":"browser-eval-script-must-not-be-empty","errorCode":null,"errorMessage":"browser/eval: script must not be empty","messagePattern":"browser/eval: script must not be empty","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/browser/src/mcp-tools/browser-tools.ts","lineNumber":668,"sourceCode":"    category: 'browser-eval',\n    inputSchema: {\n      type: 'object',\n      properties: {\n        session: { type: 'string', description: 'Session ID' },\n        script: {\n          type: 'string',\n          description: `JavaScript code to execute (max ${MAX_EVAL_SCRIPT_LENGTH} chars)`,\n          maxLength: MAX_EVAL_SCRIPT_LENGTH,\n        },\n      },\n      required: ['script'],\n    },\n    handler: async (input) => {\n      const script = input.script as string;\n\n      // Validate script length\n      if (!script || script.length === 0) {\n        throw new Error('browser/eval: script must not be empty');\n      }\n      if (script.length > MAX_EVAL_SCRIPT_LENGTH) {\n        throw new Error(`browser/eval: script exceeds maximum length of ${MAX_EVAL_SCRIPT_LENGTH} characters`);\n      }\n\n      // Check for dangerous patterns\n      for (const pattern of DANGEROUS_EVAL_PATTERNS) {\n        if (pattern.test(script)) {\n          throw new Error(`browser/eval: script contains disallowed pattern: ${pattern.source}`);\n        }\n      }\n\n      // Audit log\n      console.info(`[browser/eval] Executing script (${script.length} chars) in session ${input.session || 'default'}`);\n\n      const adapter = getAdapter(input.session as string);\n      return adapter.eval({ script });\n    },","sourceCodeStart":650,"sourceCodeEnd":686,"githubUrl":"https://github.com/ruvnet/ruflo/blob/6b01dc5a687b26b3e218f796de45ec51f8fa9e8c/v3/@claude-flow/browser/src/mcp-tools/browser-tools.ts#L650-L686","documentation":"Thrown by the browser/eval MCP tool handler when input.script is falsy or has length 0. The tool's JSON schema already marks 'script' as required, so this is the runtime guard behind the schema. It fires before any length-max or dangerous-pattern checks.","triggerScenarios":"Invoking the browser/eval tool with script: '', script: undefined, script: null, or omitting the field entirely (when the MCP transport does not enforce required fields).","commonSituations":"An LLM tool call that templated an empty expression; a caller passing a variable that evaluated to undefined; a test fixture that forgets to populate the script field.","solutions":["Ensure the script argument is a non-empty string before invoking browser/eval.","If the script is generated, fall back to a safe no-op or skip the call rather than sending an empty string.","Validate at the caller boundary with a type guard or zod schema mirroring the tool's contract."],"exampleFix":"// before\nawait evalTool.handler({ script: code ?? '' }); // throws 62 when code is null\n\n// after\nif (typeof code === 'string' && code.length > 0) {\n  await evalTool.handler({ script: code });\n}","handlingStrategy":"validation","validationCode":"function isNonEmptyScript(s) {\n  return typeof s === 'string' && s.length > 0;\n}\nif (!isNonEmptyScript(input.script)) throw new Error('script required');","typeGuard":"function isNonEmptyScript(s) { return typeof s === 'string' && s.length > 0; }","tryCatchPattern":"null","preventionTips":["Validate generated scripts at the source rather than relying on the tool's runtime guard.","Skip the browser/eval call when the script would be empty instead of sending ''."],"tags":["mcp","browser-eval","validation","typescript"],"backgroundTag":null,"analyzedSha":"6b01dc5a687b26b3e218f796de45ec51f8fa9e8c","analyzedAt":"2026-08-12T13:20:50.148Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}