{"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":"exception","errorClass":null,"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/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/browser/src/mcp-tools/browser-tools.ts#L650-L686","documentation":"Thrown by the browser/eval MCP tool handler in @claude-flow/browser when the required 'script' input is missing, undefined, or an empty string. The JSON-Schema for the tool only marks 'script' as required (presence), so an empty string passes schema checks and this handler-level guard rejects it before any dangerous-pattern scanning or adapter dispatch happens.","triggerScenarios":"Invoking the browser/eval tool with script: '' or omitting script (undefined coerced by the `input.script as string` cast); passing whitespace-only or a variable that evaluated to empty at the call site.","commonSituations":"Template literals that render to empty when a placeholder is missing (script: `${userCode}` with userCode undefined); pipelines that chain eval after an extraction step which returned nothing; LLM-driven tool calls that emit an empty script argument.","solutions":["Ensure the script string is non-empty before invoking the tool (trim and length-check at the call site)","Fix the upstream generator/placeholder that produced the empty script string","If empty input is legitimate in your flow, short-circuit with a no-op instead of calling the tool"],"exampleFix":"// before\nawait tools.invoke('browser/eval', { script: extracted }); // extracted === ''\n\n// after\nconst script = (extracted ?? '').trim();\nif (script.length === 0) return { skipped: true, reason: 'no script extracted' };\nawait tools.invoke('browser/eval', { script });","handlingStrategy":"validation","validationCode":"const script = String(input?.script ?? '').trim();\nif (script.length === 0) {\n  return { skipped: true, reason: 'empty script' };\n}\nawait tools.invoke('browser/eval', { script });","typeGuard":"const isNonEmptyScript = (s: unknown): s is string => typeof s === 'string' && s.trim().length > 0;","tryCatchPattern":null,"preventionTips":["Validate template inputs before rendering eval scripts","Default missing generated code to an explicit skip rather than an empty invoke"],"tags":["browser","eval","input-validation","mcp-tools"],"backgroundTag":"empty-required-field","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}