{"record":{"id":"b71a82370c4ef520","repo":"microsoft/playwright","slug":"webview-has-been-closed","errorCode":null,"errorMessage":"WebView has been closed","messagePattern":"WebView has been closed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/android/android.ts","lineNumber":330,"sourceCode":"    const chromeArguments = [];\n    if (proxy) {\n      chromeArguments.push(`--proxy-server=${proxy.server}`);\n      const proxyBypassRules = [];\n      if (proxy.bypass)\n        proxyBypassRules.push(...proxy.bypass.split(',').map(t => t.trim()).map(t => t.startsWith('.') ? '*' + t : t));\n      if (shouldProxyLoopback(proxy.bypass))\n        proxyBypassRules.push('<-loopback>');\n      if (proxyBypassRules.length > 0)\n        chromeArguments.push(`--proxy-bypass-list=${proxyBypassRules.join(';')}`);\n    }\n    chromeArguments.push(...args);\n    return chromeArguments;\n  }\n\n  async connectToWebView(progress: Progress, socketName: string): Promise<BrowserContext> {\n    const webView = this._webViews.get(socketName);\n    if (!webView)\n      throw new Error('WebView has been closed');\n    return await this._connectToBrowser(progress, socketName, {}, /* isWebView */ true);\n  }\n\n  private async _connectToBrowser(progress: Progress, socketName: string, options: types.BrowserContextOptions = {}, isWebView?: boolean): Promise<BrowserContext> {\n    const socket = await this._waitForLocalAbstract(progress, socketName);\n    try {\n      const androidBrowser = new AndroidBrowser(this, socket);\n      await progress.race(androidBrowser._init());\n      this._browserConnections.add(androidBrowser);\n\n      const artifactsDir = await progress.race(fs.promises.mkdtemp(ARTIFACTS_FOLDER));\n      const cleanupArtifactsDir = async () => {\n        const errors = (await removeFolders([artifactsDir])).filter(Boolean);\n        for (let i = 0; i < (errors || []).length; ++i)\n          debug('pw:android')(`exception while removing ${artifactsDir}: ${errors[i]}`);\n      };\n      gracefullyCloseSet.add(cleanupArtifactsDir);\n      socket.on('close', async () => {","sourceCodeStart":312,"sourceCodeEnd":348,"githubUrl":"https://github.com/microsoft/playwright/blob/de214f440b7e34937fe4886f046b78b757136087/packages/playwright-core/src/server/android/android.ts#L312-L348","documentation":"Error thrown by AndroidDevice.connectToWebView() when the requested WebView socket name no longer exists in the device's list of known WebViews. This means the WebView process (the Android app embedding a WebView) has terminated or its socket was unregistered, so Playwright cannot attach a CDP session to it. To resolve, verify the WebView-enabled app is running on the device (WebView sockets appear only while the app is alive), refresh the socket name via androidDevice.webViews(), and call connectToWebView() again with a currently valid socketName.","triggerScenarios":"Thrown at packages/playwright-core/src/server/android/android.ts:331 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Re-acquire the WebView: re-read androidDevice.webViews() and get a fresh handle instead of using a stale one","Listen for the 'close'/'webview' close events on the device and stop issuing commands to closed WebViews","Check that the Android app hosting the WebView is still running before automating it","Reconnect to the device (androidDevice or adb) if the whole connection dropped, then re-launch/attach the WebView"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"de214f440b7e34937fe4886f046b78b757136087","analyzedAt":"2026-09-01T05:48:36.844Z","contentChangedAt":"2026-09-01T05:48:36.844Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}