microsoft/playwright · error · Error
Launching more browsers is not allowed.
Error message
Launching more browsers is not allowed.
What it means
Thrown by BrowserTypeDispatcher.launch() when _denyLaunch is true. The Playwright server (playwrightServer / launchServer / connect / preLaunchedBrowser modes) sets denyLaunch=true on the BrowserTypeDispatcher once the server itself owns browser lifecycle, so clients cannot spawn additional browsers. This is the launch path (non-persistent).
Source
Thrown at packages/playwright-core/src/server/dispatchers/browserTypeDispatcher.ts:40
import type { BrowserType } from '../browserType';
import type { RootDispatcher } from './dispatcher';
import type * as channels from '../channels';
import type { Progress } from '../progress';
export class BrowserTypeDispatcher extends Dispatcher<BrowserType, channels.BrowserTypeChannel, RootDispatcher> implements channels.BrowserTypeChannel {
_type_BrowserType = true;
private readonly _denyLaunch: boolean;
constructor(scope: RootDispatcher, browserType: BrowserType, denyLaunch: boolean) {
super(scope, browserType, 'BrowserType', {
executablePath: browserType.executablePath(),
name: browserType.name()
});
this._denyLaunch = denyLaunch;
}
async launch(params: channels.BrowserTypeLaunchParams, progress: Progress): Promise<channels.BrowserTypeLaunchResult> {
if (this._denyLaunch)
throw new Error(`Launching more browsers is not allowed.`);
const browser = await this._object.launch(progress, params);
return { browser: new BrowserDispatcher(this, browser) };
}
async launchPersistentContext(params: channels.BrowserTypeLaunchPersistentContextParams, progress: Progress): Promise<channels.BrowserTypeLaunchPersistentContextResult> {
if (this._denyLaunch)
throw new Error(`Launching more browsers is not allowed.`);
const browserContext = await this._object.launchPersistentContext(progress, params.userDataDir, params);
const browserDispatcher = new BrowserDispatcher(this, browserContext._browser);
const contextDispatcher = BrowserContextDispatcher.from(browserDispatcher, browserContext);
return { browser: browserDispatcher, context: contextDispatcher };
}
async connectOverCDP(params: channels.BrowserTypeConnectOverCDPParams, progress: Progress): Promise<channels.BrowserTypeConnectOverCDPResult> {
if (this._denyLaunch)
throw new Error(`Launching more browsers is not allowed.`);View on GitHub (pinned to c8fc3bf8d3)
Solutions
- Use the browser the server already gave you: read preLaunchedBrowser from the init result instead of calling launch().
- If you need the client to launch, run against a plain local playwright instance rather than a denyLaunch server endpoint.
- Confirm the connection mode you are using (connect/launchServer/preLaunched) and align expectations: only the non-denyLaunch path allows launch().
Example fix
// before: launch over a managed server connection
const browser = await chromium.connect(wsEndpoint);
const extra = await chromium.launch(); // denied
// after: reuse the server-provided browser
const { browser } = await chromium.connect(wsEndpoint);
const context = await browser.newContext(); Defensive patterns
Strategy: validation
Validate before calling
const init = await playwright.initialize();
if (init.denyLaunch) throw new Error('Server denies launch(); use init.preLaunchedBrowser instead'); Type guard
function hasPreLaunchedBrowser(init: any): init is { preLaunchedBrowser: Browser } {
return !!init?.preLaunchedBrowser;
} Try / catch
try {
await chromium.launch();
} catch (e) {
if (/Launching more browsers is not allowed/.test(e.message)) { /* use preLaunchedBrowser */ }
else throw e;
} Prevention
- Read the init/denyLaunch state once at connect time and branch client logic on it.
- Treat a managed server connection as 'reuse, do not launch'.
- Run launches from local playwright when you need spawn control.
When it happens
Trigger: Calling chromium.launch() / firefox.launch() / webkit.launch() over a connection to a Playwright server whose initialize result carried denyLaunch=true (launchServer mode, connect mode, preLaunchedBrowser mode, or launchServerShared). The check fires immediately before any browser process starts.
Common situations: Connecting to a remote browser server (playwright.launchServer / browserType.connectOverCDP to a managed endpoint) and then calling launch() again from the client; MCP/remote sessions that already receive a preLaunchedBrowser but still try to spawn their own; misreading 'connect' as 'launch'.
Related errors
- Launching more browsers is not allowed.
- Connecting to Android devices is not allowed.
- Connecting to SELENIUM_REMOTE_URL is only supported by Chrom
- Path is not available when connecting remotely. Use saveAs()
- Route from har is not supported in thin clients
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/4f657118e5a24da3.
Report an issue: GitHub.