microsoft/playwright · error · Error

localPaths are not allowed when the client is not local

Error message

localPaths are not allowed when the client is not local

What it means

prepareFilesForUpload rejects localPaths (filesystem paths) when the Playwright client and server are not collocated - i.e. when isClientCollocatedWithServer is false, which happens in remote/browser-server deployments where the file system the user sees differs from the server's.

Source

Thrown at packages/playwright-core/src/server/fileUploadUtils.ts:40

import type { WritableStreamDispatcher } from './dispatchers/writableStreamDispatcher';
import type { InputFilesItems } from './dom';
import type { Frame } from './frames';
import type * as types from './types';
import type * as channels from './channels';

// Keep in sync with the client.
export const fileUploadSizeLimit = 50 * 1024 * 1024;

async function filesExceedUploadLimit(files: string[]) {
  const sizes = await Promise.all(files.map(async file => (await fs.promises.stat(file)).size));
  return sizes.reduce((total, size) => total + size, 0) >= fileUploadSizeLimit;
}

export async function prepareFilesForUpload(frame: Frame, params: Omit<channels.ElementHandleSetInputFilesParams, 'timeout'>): Promise<InputFilesItems> {
  const { payloads, streams, directoryStream } = params;
  let { localPaths, localDirectory } = params;
  if (localPaths && !frame.attribution.playwright.options.isClientCollocatedWithServer)
    throw new Error('localPaths are not allowed when the client is not local');

  if ([payloads, localPaths, localDirectory, streams, directoryStream].filter(Boolean).length !== 1)
    throw new Error('Exactly one of payloads, localPaths and streams must be provided');

  if (streams)
    localPaths = streams.map(c => (c as WritableStreamDispatcher).path());
  if (directoryStream)
    localDirectory = (directoryStream as WritableStreamDispatcher).path();

  if (localPaths) {
    for (const p of localPaths)
      assert(path.isAbsolute(p) && path.resolve(p) === p, 'Paths provided to localPaths must be absolute and fully resolved.');
  }

  let fileBuffers: {
    name: string,
    mimeType?: string,
    buffer: Buffer,

View on GitHub (pinned to c8fc3bf8d3)

Solutions

  1. Switch to setInputFiles with file payloads (read the file into a Buffer) so the bytes travel over the wire.
  2. Or use streams via the writable-stream channel when supported.
  3. Ensure the file actually exists on the server if you intend to keep paths, then run collocated.
  4. If you did not mean to run remotely, drop the wsEndpoint/server config so client and server are the same process.

Example fix

// before (remote server)
await handle.setInputFiles('/Users/me/file.pdf'); // throws
// after: send the bytes
const fs = require('fs');
await handle.setInputFiles({
  name: 'file.pdf',
  mimeType: 'application/pdf',
  buffer: fs.readFileSync('/Users/me/file.pdf'),
});
Defensive patterns

Strategy: validation

Validate before calling

// Decide path vs payload based on collocation
const remote = !!process.env.PLAYWRIGHT_WS_ENDPOINT;
if (remote) {
  await handle.setInputFiles({ name, mimeType, buffer: fs.readFileSync(localPath) });
} else {
  await handle.setInputFiles(localPath);
}

Type guard

// Heuristic: are we talking to a remote server?
function shouldUsePayload() { return !!browser._endpoint && !browser._isCollocated; }

Try / catch

null

Prevention

When it happens

Trigger: Calling element.setInputFiles(paths) with absolute filesystem paths while connected to a remote Playwright server or browser server (playwright.chromium.launchServer / connectOverCDP / ws endpoint) where the client machine is not the server machine.

Common situations: Running tests against a remote browser service; connecting via websockets to a separately-launched browser server; containerized drivers where client and server differ; misconfigured CI pointing at a remote endpoint while passing local developer-machine paths.

Related errors


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