ruvnet/ruflo · error
browser/eval: script must not be empty
Error message
browser/eval: script must not be empty
What it means
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.
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
Example fix
// before
await tools.invoke('browser/eval', { script: extracted }); // extracted === ''
// after
const script = (extracted ?? '').trim();
if (script.length === 0) return { skipped: true, reason: 'no script extracted' };
await tools.invoke('browser/eval', { script }); Defensive patterns
Strategy: validation
Validate before calling
const script = String(input?.script ?? '').trim();
if (script.length === 0) {
return { skipped: true, reason: 'empty script' };
}
await tools.invoke('browser/eval', { script }); Type guard
const isNonEmptyScript = (s: unknown): s is string => typeof s === 'string' && s.trim().length > 0;
Prevention
- Validate template inputs before rendering eval scripts
- Default missing generated code to an explicit skip rather than an empty invoke
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- browser/eval: script contains disallowed pattern
- browser/eval: script exceeds maximum length of
- allowedMcpTools entries must be non-empty strings
- allowedMcpTools must have ≥1 entry
- Buffer too small for RVFP preamble
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/0a257c3bb625887d.
Report an issue: GitHub.
Appendix: source
Thrown at v3/@claude-flow/browser/src/mcp-tools/browser-tools.ts:668
category: 'browser-eval',
inputSchema: {
type: 'object',
properties: {
session: { type: 'string', description: 'Session ID' },
script: {
type: 'string',
description: `JavaScript code to execute (max ${MAX_EVAL_SCRIPT_LENGTH} chars)`,
maxLength: MAX_EVAL_SCRIPT_LENGTH,
},
},
required: ['script'],
},
handler: async (input) => {
const script = input.script as string;
// Validate script length
if (!script || script.length === 0) {
throw new Error('browser/eval: script must not be empty');
}
if (script.length > MAX_EVAL_SCRIPT_LENGTH) {
throw new Error(`browser/eval: script exceeds maximum length of ${MAX_EVAL_SCRIPT_LENGTH} characters`);
}
// Check for dangerous patterns
for (const pattern of DANGEROUS_EVAL_PATTERNS) {
if (pattern.test(script)) {
throw new Error(`browser/eval: script contains disallowed pattern: ${pattern.source}`);
}
}
// Audit log
console.info(`[browser/eval] Executing script (${script.length} chars) in session ${input.session || 'default'}`);
const adapter = getAdapter(input.session as string);
return adapter.eval({ script });
},View on GitHub (pinned to fa13ee4ad6)