microsoft/playwright · error · Error

Path is not available when connecting remotely. Use saveAs()

Error message

Path is not available when connecting remotely. Use saveAs() to save a local copy.

What it means

Thrown by Artifact.pathAfterFinished() when the connection is remote (a thin/remote client over WS). Remote clients cannot access the server's filesystem path, so only saveAs(path) (which streams the artifact) is allowed. The guard is `this._connection.isRemote()`.

Source

Thrown at packages/playwright-core/src/client/artifact.ts:34

import fs from 'fs';

import { ChannelOwner } from './channelOwner';
import { Stream } from './stream';
import { mkdirIfNeeded } from './fileUtils';
import { kNoTimeout } from './timeoutSettings';

import type * as channels from './channels';
import type { Readable } from 'stream';

export class Artifact extends ChannelOwner<channels.ArtifactChannel> {
  static from(channel: channels.ArtifactChannel): Artifact {
    return (channel as any)._object;
  }

  async pathAfterFinished(): Promise<string> {
    if (this._connection.isRemote())
      throw new Error(`Path is not available when connecting remotely. Use saveAs() to save a local copy.`);
    return (await this._channel.pathAfterFinished({}, kNoTimeout)).value;
  }

  async saveAs(path: string): Promise<void> {
    if (!this._connection.isRemote()) {
      await this._channel.saveAs({ path }, kNoTimeout);
      return;
    }

    const result = await this._channel.saveAsStream({}, kNoTimeout);
    const stream = Stream.from(result.stream);
    await mkdirIfNeeded(path);
    await new Promise((resolve, reject) => {
      stream.stream().pipe(fs.createWriteStream(path))
          .on('finish' as any, resolve)
          .on('error' as any, reject);
    });
  }

View on GitHub (pinned to c8fc3bf8d3)

Solutions

  1. Use saveAs() to stream a local copy: `await download.saveAs('/tmp/file')`.
  2. Restructure code to always use saveAs() so it works both local and remote.
  3. If you need the path pattern, build it locally after saveAs rather than relying on the server path.

Example fix

// before
const p = await download.path();
// after
const p = '/tmp/downloaded.bin';
await download.saveAs(p);
Defensive patterns

Strategy: type-guard

Validate before calling

const isRemote = (artifact as any)._connection?.isRemote?.();
if (isRemote) {
  await artifact.saveAs(localPath); // never call path()
} else {
  const p = await artifact.pathAfterFinished();
}

Type guard

function isRemoteArtifact(a: any): boolean {
  return !!a?._connection?.isRemote?.();
}

Prevention

When it happens

Trigger: Calling `download.path()` or `artifact.pathAfterFinished()` after connecting via BrowserType.connect() to a remote server, or using playwright-client in thin-client mode. Applies to downloads, video artifacts, and traces created server-side.

Common situations: Reusing code that calls download.path() locally in a CI step that now connects to a remote browser service; running tests against Browserless/cloud providers where the browser runs on another host.

Related errors


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