{"record":{"id":"c0663a5e6fc3d77c","repo":"microsoft/playwright","slug":"malformed-endpoint-did-you-use-android-launchserv","errorCode":null,"errorMessage":"Malformed endpoint. Did you use Android.launchServer method?","messagePattern":"Malformed endpoint\\. Did you use Android\\.launchServer method\\?","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/client/android.ts","lineNumber":86,"sourceCode":"  }\n\n  async connect(endpoint: string, options: Parameters<api.Android['connect']>[1] = {}): Promise<api.AndroidDevice> {\n    return await this._wrapApiCall(async () => {\n      const deadline = options.timeout ? monotonicTime() + options.timeout : 0;\n      const headers = { 'x-playwright-browser': 'android', ...options.headers };\n      const connectParams: channels.LocalUtilsConnectParams = { endpoint, headers, slowMo: options.slowMo };\n      const connection = await connectToEndpoint(this._connection, connectParams, { signal: undefined, timeout: options.timeout || 0 });\n\n      let device: AndroidDevice;\n      connection.on('close', () => {\n        device?._didClose();\n      });\n\n      const result = await raceAgainstDeadline(async () => {\n        const playwright = await connection!.initializePlaywright();\n        if (!playwright._initializer.preConnectedAndroidDevice) {\n          connection.close();\n          throw new Error('Malformed endpoint. Did you use Android.launchServer method?');\n        }\n        device = AndroidDevice.from(playwright._initializer.preConnectedAndroidDevice!);\n        device._shouldCloseConnectionOnClose = true;\n        device.on(Events.AndroidDevice.Close, () => connection.close());\n        return device;\n      }, deadline);\n      if (!result.timedOut) {\n        return result.result;\n      } else {\n        connection.close();\n        throw new Error(`Timeout ${options.timeout}ms exceeded`);\n      }\n    });\n  }\n}\n\nexport class AndroidDevice extends ChannelOwner<channels.AndroidDeviceChannel> implements api.AndroidDevice {\n  readonly _timeoutSettings: TimeoutSettings;","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/client/android.ts#L68-L104","documentation":"Thrown during Android.connect() when the remote endpoint initializes Playwright but the initializer has no preConnectedAndroidDevice. The connect flow expects the endpoint to be an Android server that pre-attaches a device; absence of that field means the endpoint was not started via an Android launcher. The connection is closed before throwing.","triggerScenarios":"Calling `android.connect(wsEndpoint)` where wsEndpoint points to a regular chromium BrowserType.launchServer endpoint, or any non-Android WS server. The raceAgainstDeadline resolves, but playwright._initializer.preConnectedAndroidDevice is falsy.","commonSituations":"Reusing a wsEndpoint captured from `chromium.launchServer()` for an Android connect call; pointing at a stale or wrong-service URL; version mismatch between server (non-Android build) and Android client.","solutions":["Ensure the endpoint was produced by an Android-capable server (Android driver running on the host).","Verify the wsEndpoint value and that the server process is the Android variant.","Use BrowserType.connectOverCDP/connect for non-Android endpoints instead."],"exampleFix":"// before\nconst device = await android.connect('ws://host:9222/non-android-endpoint');\n// after\nconst device = await android.connect('ws://android-host:9999/android-ws');","handlingStrategy":"validation","validationCode":"// Ensure the endpoint is an Android server before connecting\nif (!/android/i.test(endpoint))\n  console.warn('Endpoint may not be an Android server; connect may fail with malformed-endpoint.');","typeGuard":null,"tryCatchPattern":"try {\n  const device = await android.connect(endpoint, { timeout: 30000 });\n} catch (e) {\n  if ((e as Error).message.includes('Malformed endpoint'))\n    throw new Error(`Endpoint ${endpoint} is not an Android server.`);\n  throw e;\n}","preventionTips":["Capture wsEndpoints from the matching launcher (Android) only.","Tag endpoint URLs by service to avoid cross-use."],"tags":["android","connect","endpoint-validation"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}