{"record":{"id":"3c514db3ed6894c6","repo":"microsoft/playwright","slug":"cdp-session-is-only-available-in-chromium","errorCode":null,"errorMessage":"CDP session is only available in Chromium","messagePattern":"CDP session is only available in Chromium","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/dispatchers/browserContextDispatcher.ts","lineNumber":378,"sourceCode":"  }\n\n  async disableRecorder(params: channels.BrowserContextDisableRecorderParams, progress: Progress): Promise<void> {\n    const recorder = await progress.race(Recorder.existingForContext(this._context));\n    if (recorder)\n      await progress.race(recorder.setMode('none'));\n  }\n\n  async exposeConsoleApi(params: channels.BrowserContextExposeConsoleApiParams, progress: Progress): Promise<void> {\n    await this._context.exposeConsoleApi(progress);\n  }\n\n  async pause(params: channels.BrowserContextPauseParams, progress: Progress) {\n    // Debugger will take care of this.\n  }\n\n  async newCDPSession(params: channels.BrowserContextNewCDPSessionParams, progress: Progress): Promise<channels.BrowserContextNewCDPSessionResult> {\n    if (this._object._browser.options.browserType !== 'chromium')\n      throw new Error(`CDP session is only available in Chromium`);\n    if (!params.page && !params.frame || params.page && params.frame)\n      throw new Error(`CDP session must be initiated with either Page or Frame, not none or both`);\n    const crBrowserContext = this._object as CRBrowserContext;\n    return { session: new CDPSessionDispatcher(this, await progress.race(crBrowserContext.newCDPSession((params.page ? params.page as PageDispatcher : params.frame as FrameDispatcher)._object))) };\n  }\n\n  async clockFastForward(params: channels.BrowserContextClockFastForwardParams, progress: Progress): Promise<channels.BrowserContextClockFastForwardResult> {\n    await progress.race(this._context.clock.fastForward(params.ticksString ?? params.ticksNumber ?? 0));\n  }\n\n  async clockInstall(params: channels.BrowserContextClockInstallParams, progress: Progress): Promise<channels.BrowserContextClockInstallResult> {\n    await progress.race(this._context.clock.install(params.timeString ?? params.timeNumber ?? undefined));\n  }\n\n  async clockPauseAt(params: channels.BrowserContextClockPauseAtParams, progress: Progress): Promise<channels.BrowserContextClockPauseAtResult> {\n    await progress.race(this._context.clock.pauseAt(params.timeString ?? params.timeNumber ?? 0));\n    this._clockPaused = true;\n  }","sourceCodeStart":360,"sourceCodeEnd":396,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/dispatchers/browserContextDispatcher.ts#L360-L396","documentation":"Thrown by BrowserContextDispatcher.newCDPSession() unless the context's browser type is chromium. Chrome DevTools Protocol (CDP) is a Chromium-only feature; Firefox and WebKit have no equivalent exposed by Playwright, so requesting a CDP session against them is rejected up front. The browserType check uses this._object._browser.options.browserType.","triggerScenarios":"Calling browserContext.newCDPSession(pageOrFrame) (or the newCDPSession RPC) on a context launched under firefox or webkit: chromium.firefox.launch() / webkit.launch() followed by context.newCDPSession(). Also triggered by cross-browser test code that calls newCDPSession unconditionally without checking the project.","commonSituations":"Shared helpers that drop down to CDP for performance/tracing/emulation and run across all browser projects; tests migrated from a chromium-only suite to a multi-browser config; conditionals missing for the firefox/webkit projects.","solutions":["Guard the CDP call with a browser-type check: const isChromium = context.browser().browserType().name() === 'chromium'; only call newCDPSession when true.","In the Playwright test runner, scope CDP-using code to the chromium project (test.configure / test.use) or branch on browserName from the fixture.","Replace the CDP dependency with a cross-browser Playwright API where one exists (e.g. context.tracing, route, addInitScript)."],"exampleFix":"// before: crashes on firefox/webkit\nconst cdp = await context.newCDPSession(page);\n\n// after: chromium-only branch\nif (page.context().browser().browserType().name() !== 'chromium')\n  test.skip(true, 'CDP only available in chromium');\nconst cdp = await context.newCDPSession(page);","handlingStrategy":"type-guard","validationCode":"function isChromium(browserOrContext): boolean {\n  const bt = browserOrContext.browser?.()?.browserType?.() ?? browserOrContext.browserType?.();\n  return bt?.name?.() === 'chromium';\n}\nif (!isChromium(context)) throw new Error('newCDPSession requires chromium');","typeGuard":"function isChromiumContext(ctx): ctx is BrowserContext {\n  return ctx.browser()?.browserType().name() === 'chromium';\n}","tryCatchPattern":null,"preventionTips":["Centralize CDP usage in a helper that early-returns or skips on non-chromium browsers.","In the test runner, scope CDP-dependent tests to the chromium project.","Prefer Playwright's cross-browser APIs (context.tracing, route, addInitScript) over raw CDP."],"tags":["cdp","chromium","browser-type","validation"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}