microsoft/playwright · error · Error

Browser '${this.name}' is not open. Run playwright-cli${t

Error message

Browser '${this.name}' is not open. Run

  playwright-cli${this.name !== 'default' ? ` -s=${this.name}` : ''} open

to start the browser session.

What it means

Thrown by Session.run after the compatibility check passes but _connect() returns no socket — meaning the named session file exists and is version-compatible, but no daemon process is listening on the configured socketPath (the daemon was never started, has exited, or crashed).

Source

Thrown at packages/playwright-core/src/tools/cli-client/session.ts:51

  private _sessionFile: SessionFile;

  constructor(sessionFile: SessionFile) {
    this.config = sessionFile.config;
    this.name = this.config.name;
    this._sessionFile = sessionFile;
  }

  isCompatible(clientInfo: ClientInfo): boolean {
    return compareSemver(clientInfo.version, this.config.version) >= 0;
  }

  async run(clientInfo: ClientInfo, args: MinimistArgs, options?: { raw?: boolean, json?: boolean }): Promise<{ text: string, isError?: boolean }> {
    if (!this.isCompatible(clientInfo))
      throw new Error(`Client is v${clientInfo.version}, session '${this.name}' is v${this.config.version}. Run\n\n  playwright-cli${this.name !== 'default' ? ` -s=${this.name}` : ''} open\n\nto restart the browser session.`);

    const { socket } = await this._connect();
    if (!socket)
      throw new Error(`Browser '${this.name}' is not open. Run\n\n  playwright-cli${this.name !== 'default' ? ` -s=${this.name}` : ''} open\n\nto start the browser session.`);
    return await SocketConnectionClient.sendAndClose(socket, 'run', { args, cwd: process.cwd(), raw: options?.raw, json: options?.json });
  }

  async stop(): Promise<{ wasOpen: boolean }> {
    if (!await this.canConnect())
      return { wasOpen: false };
    await this._stopDaemon();
    return { wasOpen: true };
  }

  async deleteData(): Promise<{ existed: boolean, deletedUserDataDir: boolean }> {
    await this.stop();

    const dataDirs = await fs.promises.readdir(this._sessionFile.daemonDir).catch(() => []);
    const matchingEntries = dataDirs.filter(file => file === `${this.name}.session` || file.startsWith(`ud-${this.name}-`));
    if (matchingEntries.length === 0)
      return { existed: false, deletedUserDataDir: false };

View on GitHub (pinned to c8fc3bf8d3)

Solutions

  1. Run playwright-cli open (add -s=<name> if non-default) to (re)start the daemon.
  2. If open claims it is already running but the socket is dead, run session.stop()/close first to clean up, then open.
  3. Check the .err log under clientInfo.daemonProfilesDir for the crash cause if the daemon keeps dying.

Example fix

# before
playwright-cli -s=ci screenshot   # daemon not running -> throws

# after
playwright-cli -s=ci open
playwright-cli -s=ci screenshot
Defensive patterns

Strategy: validation

Validate before calling

// Probe the socket before issuing the command.
const canConnect = await session.canConnect(); // returns boolean, no throw
if (!canConnect) {
  await Session.startDaemon(clientInfo, { session: session.name } as any, 'open');
}

Type guard

function isBrowserNotOpenError(e: unknown): boolean {
  return e instanceof Error && e.message.includes("is not open");
}

Try / catch

try {
  await session.run(clientInfo, args);
} catch (e) {
  if (isBrowserNotOpenError(e)) {
    await Session.startDaemon(clientInfo, { session: session.name } as any, 'open');
    await session.run(clientInfo, args);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling any session-scoped command when the daemon for that session is not running; the daemon died after the session file was written; the machine rebooted leaving a stale session file.

Common situations: Reboot/logoff killed the daemon; an earlier open failed silently; long gap between open and the command; OS cleaned up the socket path.

Related errors


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