microsoft/playwright · error · Error

Provide an object with a `url`, `path` or `content` property

Error message

Provide an object with a `url`, `path` or `content` property

What it means

Thrown by Frame._addScriptTag() when neither a url nor content property is supplied in the params object. The method destructures both with null defaults and checks if both are falsy. The message also references 'path' because the public API accepts path, but path is resolved to content by the time it reaches this server-side method.

Source

Thrown at packages/playwright-core/src/server/frames.ts:1035

    url?: string,
    content?: string,
    type?: string,
  }): Promise<dom.ElementHandle> {
    return await progress.race(this._addScriptTag(params));
  }

  private async _addScriptTag(params: {
    url?: string,
    content?: string,
    type?: string,
  }): Promise<dom.ElementHandle> {
    const {
      url = null,
      content = null,
      type = ''
    } = params;
    if (!url && !content)
      throw new Error('Provide an object with a `url`, `path` or `content` property');

    const context = await this.mainContext();
    return this._raceWithCSPError(async () => {
      if (url !== null)
        return (await context.evaluateHandle(addScriptUrl, { url, type })).asElement()!;
      const result = (await context.evaluateHandle(addScriptContent, { content: content!, type })).asElement()!;
      // Another round trip to the browser to ensure that we receive CSP error messages
      // (if any) logged asynchronously in a separate task on the content main thread.
      if (this._page.delegate.cspErrorsAsynchronousForInlineScripts)
        await context.evaluate(() => true);
      return result;
    });

    async function addScriptUrl(params: { url: string, type: string }): Promise<HTMLElement> {
      const script = document.createElement('script');
      script.src = params.url;
      if (params.type)
        script.type = params.type;

View on GitHub (pinned to c8fc3bf8d3)

Solutions

  1. Provide at least one of { url: 'https://...' }, { content: 'console.log(1)' }, or { path: './script.js' } to addScriptTag.
  2. Check that the variable holding the url or content is not undefined before passing it: if (scriptUrl) await page.addScriptTag({ url: scriptUrl }).
  3. Use TypeScript with the proper types to catch missing properties at compile time.

Example fix

// before
await page.addScriptTag({ src: 'https://cdn.example.com/lib.js' });

// after
await page.addScriptTag({ url: 'https://cdn.example.com/lib.js' });
Defensive patterns

Strategy: validation

Validate before calling

function validateScriptTagParams(params) {
  if (!params.url && !params.content && !params.path)
    throw new Error('addScriptTag requires url, path, or content');
  return params;
}

Type guard

function isValidScriptTagParams(params: any): params is { url: string } | { content: string } | { path: string } {
  return typeof params.url === 'string' && params.url.length > 0
    || typeof params.content === 'string' && params.content.length > 0
    || typeof params.path === 'string' && params.path.length > 0;
}

Prevention

When it happens

Trigger: Calling page.addScriptTag() or frame.addScriptTag() with an empty object {}, an object missing all three properties, or with a property set to an empty string or undefined. Also when the path property is used but the file read fails before reaching this code, leaving url and content both null.

Common situations: Typo in property name (e.g., { src: '...' } instead of { url: '...' }). Passing a variable that is undefined at runtime. Conditionally building the params object and forgetting to set at least one branch. Using the older Puppeteer-style API where the property was named file.

Related errors


AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12). Data as JSON: /api/errors/bb0765447f7c0f23. Report an issue: GitHub.