{"record":{"id":"db3889bebc81dec4","repo":"microsoft/playwright","slug":"no-mobile-safari-tabs-found-at-this-proxybase","errorCode":null,"errorMessage":"No Mobile Safari tabs found at ${this._proxyBase}/json — open Safari first.","messagePattern":"No Mobile Safari tabs found at (.+?)/json — open Safari first\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/webkit/webview/wvBrowser.ts","lineNumber":210,"sourceCode":"  _page!: WVPage;\n\n  constructor(parent: SdkObject, proxyBase: string, headers: { [key: string]: string }, syncServer: SyncServer, directPageTransport: ConnectOverCDPTransport | undefined, options: BrowserOptions) {\n    super(parent, options);\n    this._proxyBase = proxyBase;\n    this._headers = headers;\n    this._syncServer = syncServer;\n    this._directPageTransport = directPageTransport;\n    this._context = new WVBrowserContext(this);\n  }\n\n  async _initialize(): Promise<void> {\n    await this._context.initialize();\n    if (this._directPageTransport) {\n      await this._attachTab('rdp-transport', this._directPageTransport);\n    } else {\n      await this._syncTabs();\n      if (!this._tabs.size)\n        throw new Error(`No Mobile Safari tabs found at ${this._proxyBase}/json — open Safari first.`);\n    }\n    this._page = this._firstTab().page;\n  }\n\n  private _firstTab(): TabEntry {\n    return this._tabs.values().next().value as TabEntry;\n  }\n\n  async _syncTabs(): Promise<void> {\n    const tabs = await listTabs(this._proxyBase, this._headers);\n    const seen = new Set<string>();\n    for (const tab of tabs) {\n      const pageId = pageIdFromWsUrl(tab.webSocketDebuggerUrl);\n      seen.add(pageId);\n      if (this._tabs.has(pageId))\n        continue;\n      try {\n        await this._attachTab(pageId, new DeferredWebSocketTransport(tab.webSocketDebuggerUrl, this._headers));","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/webkit/webview/wvBrowser.ts#L192-L228","documentation":"After listing tabs from ios_webkit_debug_proxy's /json, WVBrowser._initialize requires at least one debuggable Safari tab to attach to. If the list came back empty (Safari not open, or no tab with a webSocketDebuggerUrl), connection aborts with a directive to open Safari first. This is the most common startup failure for iOS webview automation.","triggerScenarios":"Connecting to iOS Safari while Safari has no open tab; Safari open but the page is not debuggable (private browsing, native view); the device locked; web inspector disabled on the device.","commonSituations":"Forgot to open Safari on the iOS device before connecting; Web Inspector / remote automation disabled in iOS Settings; device screen locked; using a non-Safari WKWebView with no equivalent tab exposed by the proxy.","solutions":["On the device: open Safari and load any page, then retry connectOverCDP.","Enable Settings > Safari > Advanced > Web Inspector and (if needed) remote automation.","Ensure the device is unlocked and trusted, and the proxy can still see the tab via /json."],"exampleFix":"// before\n// (Safari closed on device)\nawait webkit.connectOverCDP('http://localhost:27753'); // No Mobile Safari tabs found\n\n// after\n// 1. On device: open Safari, navigate to a page.\n// 2. Then:\nawait webkit.connectOverCDP('http://localhost:27753');","handlingStrategy":"validation","validationCode":"async function ensureTab(base) {\n  const tabs = await (await fetch(`${base}/json`)).json();\n  const usable = tabs.filter(t => !!t.webSocketDebuggerUrl);\n  if (!usable.length) throw new Error('Open Safari on the device and load a page before connecting.');\n}\nawait ensureTab(endpointBase);","typeGuard":null,"tryCatchPattern":"try { browser = await webkit.connectOverCDP(base); }\ncatch (e) {\n  if (/No Mobile Safari tabs found/i.test(String(e.message))) {\n    throw new Error('Open Safari and a page on the device, then retry.');\n  }\n  throw e;\n}","preventionTips":["Open Safari and navigate to a page before each connectOverCDP.","Enable Settings > Safari > Advanced > Web Inspector.","Keep the device unlocked while tests run.","Verify via /json that a tab with webSocketDebuggerUrl is present."],"tags":["webview","ios","safari","setup"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}