microsoft/playwright · error · Error

Timeout ${options.timeout}ms exceeded

Error message

Timeout ${options.timeout}ms exceeded

What it means

Thrown at the end of Android.connect() when raceAgainstDeadline reports timedOut=true, meaning the connect flow did not complete within options.timeout ms. The connection is closed and the error interpolates the requested timeout value.

Source

Thrown at packages/playwright-core/src/client/android.ts:97

        device?._didClose();
      });

      const result = await raceAgainstDeadline(async () => {
        const playwright = await connection!.initializePlaywright();
        if (!playwright._initializer.preConnectedAndroidDevice) {
          connection.close();
          throw new Error('Malformed endpoint. Did you use Android.launchServer method?');
        }
        device = AndroidDevice.from(playwright._initializer.preConnectedAndroidDevice!);
        device._shouldCloseConnectionOnClose = true;
        device.on(Events.AndroidDevice.Close, () => connection.close());
        return device;
      }, deadline);
      if (!result.timedOut) {
        return result.result;
      } else {
        connection.close();
        throw new Error(`Timeout ${options.timeout}ms exceeded`);
      }
    });
  }
}

export class AndroidDevice extends ChannelOwner<channels.AndroidDeviceChannel> implements api.AndroidDevice {
  readonly _timeoutSettings: TimeoutSettings;
  private _webViews = new Map<string, AndroidWebView>();
  private _android: Android;
  _shouldCloseConnectionOnClose = false;

  static from(androidDevice: channels.AndroidDeviceChannel): AndroidDevice {
    return (androidDevice as any)._object;
  }

  input: AndroidInput;

  constructor(parent: ChannelOwner, type: string, guid: string, initializer: channels.AndroidDeviceInitializer) {

View on GitHub (pinned to c8fc3bf8d3)

Solutions

  1. Increase options.timeout to a realistic value for device enumeration.
  2. Verify network reachability and that the Android server/port is open.
  3. Retry with backoff if the failure is transient network flakiness.

Example fix

// before
const device = await android.connect(endpoint, { timeout: 5000 });
// after
const device = await android.connect(endpoint, { timeout: 60000 });
Defensive patterns

Strategy: retry

Validate before calling

if (typeof options.timeout === 'number' && options.timeout < 10000)
  console.warn('Android connect timeout <10s may be too short.');

Try / catch

let lastErr;
for (let attempt = 0; attempt < 3; attempt++) {
  try { return await android.connect(endpoint, { timeout: 60000 }); }
  catch (e) {
    lastErr = e;
    if (!(e as Error).message.includes('Timeout')) throw e;
  }
}
throw lastErr;

Prevention

When it happens

Trigger: Calling `android.connect(endpoint, { timeout: 5000 })` against an unreachable, slow, or hung server. The deadline (monotonicTime + timeout) expires before initialization completes.

Common situations: Network latency, firewall blocking the WS port, server boot slow on first device enumeration, or timeout set lower than realistic handshake time. Note options.timeout of 0 means no timeout (deadline stays 0).

Understand the failure class

Related errors


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