microsoft/playwright · error · Error
Either path or content property must be present
Error message
Either path or content property must be present
What it means
Thrown at the end of evaluationScript() when the `fun` object form has neither `content` nor `path`. The helper accepts a function, a string, or an object { path?, content? }; reaching the final throw means none of those branches matched a usable source.
Source
Thrown at packages/playwright-core/src/client/clientHelper.ts:51
export async function evaluationScript(fun: Function | string | { path?: string, content?: string }, arg?: any, addSourceUrl: boolean = true): Promise<string> {
if (typeof fun === 'function') {
const source = fun.toString();
const argString = Object.is(arg, undefined) ? 'undefined' : JSON.stringify(arg);
return `(${source})(${argString})`;
}
if (arg !== undefined)
throw new Error('Cannot evaluate a string with arguments');
if (isString(fun))
return fun;
if (fun.content !== undefined)
return fun.content;
if (fun.path !== undefined) {
let source = await fs.promises.readFile(fun.path, 'utf8');
if (addSourceUrl)
source = addSourceUrlToScript(source, fun.path);
return source;
}
throw new Error('Either path or content property must be present');
}
export async function initScriptSourceWithExposedFunctions(fun: Function, arg: any, expose: (name: string, callback: Function) => Promise<void>): Promise<string> {
const exposePromises: Promise<void>[] = [];
const serialized = serializeAsCallArgument(arg, value => {
if (typeof value === 'function') {
const name = kFunctionBindingPrefix + createGuid();
exposePromises.push(expose(name, value));
return { fn: name };
}
return { fallThrough: value };
});
await Promise.all(exposePromises);
// Bindings backing the functions are registered through their own init scripts
// that are guaranteed to run first, so the controller is available here.
return `(${fun.toString()})(globalThis['${kBindingsControllerProperty}'].parseInitScriptArg(${JSON.stringify(serialized)}))`;
}
View on GitHub (pinned to c8fc3bf8d3)
Solutions
- Provide content: `evaluationScript({ content: 'window.x=1' })`.
- Or provide path: `evaluationScript({ path: './init.js' })`.
- Double-check key names are exactly 'path' or 'content'.
Example fix
// before
await evaluationScript({ contents: 'window.x=1' });
// after
await evaluationScript({ content: 'window.x=1' }); Defensive patterns
Strategy: validation
Validate before calling
function isScriptObject(v: any): boolean {
return typeof v === 'object' && v !== null
&& (typeof v.content === 'string' || typeof v.path === 'string');
}
if (!isFunctionScript(s) && typeof s !== 'string' && !isScriptObject(s))
throw new Error("Provide { path } or { content }."); Type guard
function hasPathOrContent(v: any): v is { path?: string; content?: string } {
return typeof v === 'object' && v !== null
&& (typeof v.path === 'string' || typeof v.content === 'string');
} Prevention
- Use the exact keys 'path' or 'content' (not 'file'/'contents'/'source').
- Validate dynamic script-option objects before passing them.
When it happens
Trigger: Passing `evaluationScript({})`, or an object with typos like `{ contents: '...' }` or `{ filename: '...' }`. Both fun.content and fun.path are undefined, so execution falls through.
Common situations: Building the options object dynamically and omitting both keys; misreading the API and using `file`/`source` instead of `path`/`content`.
Related errors
- Cannot evaluate a string with arguments
- Invalid input image
- Invalid output dimensions
- Error while parsing selector `${selector}` - selector cannot
- Cannot find .trace file
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/c3e010312013ea61.
Report an issue: GitHub.