{"record":{"id":"43646d965c5f10b5","repo":"microsoft/playwright","slug":"page-expected-page-or-frame-43646d","errorCode":null,"errorMessage":"page: expected Page or Frame","messagePattern":"page: expected Page or Frame","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/chromium/crBrowser.ts","lineNumber":609,"sourceCode":"      browserContextId: this._browserContextId,\n    });\n  }\n\n  serviceWorkers(): CRServiceWorker[] {\n    return Array.from(this._browser._serviceWorkers.values()).filter(serviceWorker => serviceWorker.browserContext === this);\n  }\n\n  async newCDPSession(page: Page | Frame): Promise<CDPSession> {\n    let targetId: string | null = null;\n    if (page instanceof Page) {\n      targetId = (page.delegate as CRPage)._targetId;\n    } else if (page instanceof Frame) {\n      const session = (page._page.delegate as CRPage)._sessions.get(page._id);\n      if (!session)\n        throw new Error(`This frame does not have a separate CDP session, it is a part of the parent frame's session`);\n      targetId = session._targetId;\n    } else {\n      throw new Error('page: expected Page or Frame');\n    }\n\n    const rootSession = await this._browser._clientRootSession();\n    return rootSession.attachToTarget(targetId);\n  }\n}\n\nexport function shouldProxyLoopback(bypass: string | undefined) {\n  if (process.env.PLAYWRIGHT_DISABLE_FORCED_CHROMIUM_PROXIED_LOOPBACK)\n    return false;\n  const hosts = (bypass || '').split(',').map(s => s.trim());\n  const shouldBypassSomeLoopback = ['localhost', '127.0.0.1', '::1', '[::]', '[::1]', '<loopback>', '<-loopback>'].some(host => hosts.includes(host));\n  return !shouldBypassSomeLoopback;\n}\n","sourceCodeStart":591,"sourceCodeEnd":624,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/chromium/crBrowser.ts#L591-L624","documentation":"Thrown by Chromium's newCDPSession(page) when the argument is neither a Page nor a Frame instance. The method (crBrowser.ts:609) is the implementation of the chromium-only CDP bridge BrowserContext.newCDPSession; the else branch fires only when the runtime type check fails. The same call also rejects frames without their own CDP session, but with a different message.","triggerScenarios":"Calling browser.newCDPSession(worker) (a Worker, not a Page/Frame); passing a BrowserContext, JSHandle, ElementHandle, or a plain/stub object; passing a Frame belonging to a different browser instance.","commonSituations":"Trying to attach a CDP session to a WebWorker (workers use a separate target attachment path); test doubles/mocks substituting for Page; cross-browser frame references after context close.","solutions":["Pass an actual Page (from browserContext.newPage()) or a Frame (from page.frames() / page.mainFrame() / childFrames()).","For service/shared workers, attach to the worker target via the Browser CDP target API instead of newCDPSession.","If you hold a value of unknown shape, narrow it with instanceof Page / instanceof Frame before calling."],"exampleFix":"// before\nconst session = await context.newCDPSession(worker);\n// after\nconst session = await context.newCDPSession(page);","handlingStrategy":"type-guard","validationCode":"// Validate before opening a CDP session\nimport { Page, Frame } from 'playwright';\nfunction isPageOrFrame(v: unknown): v is Page | Frame {\n  return v instanceof Page || v instanceof Frame;\n}\nif (!isPageOrFrame(target))\n  throw new TypeError('newCDPSession expects a Page or Frame');\nconst session = await context.newCDPSession(target);","typeGuard":"function isPageOrFrame(v: unknown): v is Page | Frame {\n  return v instanceof Page || v instanceof Frame;\n}","tryCatchPattern":null,"preventionTips":["Type the parameter at the API boundary as Page | Frame so TS rejects Worker/BrowserContext at compile time.","Never pass values from page.workers() to newCDPSession.","If you handle unknown values, narrow with instanceof before calling."],"tags":["cdp","chromium","type-error","browser"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}