microsoft/playwright · error · Error
Cannot use --mobile together with --device, pick one.
Error message
Cannot use --mobile together with --device, pick one.
What it means
Thrown by configFromCLIOptions() when both --mobile and --device are supplied. --mobile is a shorthand that auto-selects a device preset ('iPhone 17' for webkit, 'Pixel 10' otherwise), so it is mutually exclusive with an explicit --device name. The guard prevents two sources of device-emulation configuration from contradicting each other.
Source
Thrown at packages/playwright-core/src/tools/mcp/config.ts:309
function configFromCLIOptions(cliOptions: CLIOptions): Config & { configFile?: string } {
const { browserName, channel } = resolveBrowserParam(cliOptions.browser);
// Launch options
const launchOptions: playwrightTypes.LaunchOptions = {
channel,
executablePath: cliOptions.executablePath,
headless: cliOptions.headless,
};
// --sandbox was passed, enable the sandbox
// --no-sandbox was passed, disable the sandbox
if (cliOptions.sandbox !== undefined)
launchOptions.chromiumSandbox = cliOptions.sandbox;
let device = cliOptions.device;
if (cliOptions.mobile) {
if (device)
throw new Error('Cannot use --mobile together with --device, pick one.');
if (browserName === 'firefox')
throw new Error('--mobile is not supported with the Firefox browser.');
device = browserName === 'webkit' ? 'iPhone 17' : 'Pixel 10';
}
if (device && cliOptions.cdpEndpoint)
throw new Error('Device emulation is not supported with cdpEndpoint.');
// Context options
const contextOptions: playwrightTypes.BrowserContextOptions = device ? playwright.devices[device] : {};
if (cliOptions.proxyServer) {
const proxy: playwrightTypes.LaunchOptions['proxy'] = { server: cliOptions.proxyServer };
if (cliOptions.proxyBypass)
proxy.bypass = cliOptions.proxyBypass;
// Set on both to ensure CLI takes precedence over any proxy set in the config file
// (launchOptions.proxy applies at browser launch, contextOptions.proxy at context creation).
launchOptions.proxy = proxy;View on GitHub (pinned to c8fc3bf8d3)
Solutions
- Remove one of the two flags. Keep --device if you want a specific Playwright device descriptor, or --mobile if you want the auto-selected default preset.
- If flags come from a config file or environment, audit that file for both keys being set and remove one.
- Check any wrapper script or alias that appends flags automatically.
Example fix
// before playwright mcp --mobile --device "iPhone 15" // after (explicit device) playwright mcp --device "iPhone 15" // after (auto mobile preset) playwright mcp --mobile
Defensive patterns
Strategy: validation
Validate before calling
if (cliOptions.mobile && cliOptions.device) {
throw new Error('Choose either --mobile or --device, not both.');
} Type guard
function hasMutuallyExclusiveDevice(opts: { mobile?: boolean; device?: string }): boolean {
return Boolean(opts.mobile) && Boolean(opts.device);
} Prevention
- Document which of --mobile vs --device your project standardizes on and use only that.
- Validate assembled CLI options in a wrapper script before invoking the MCP server.
- Avoid blanket flag lists that get reused across different commands.
When it happens
Trigger: Invoking the MCP CLI with both flags set, e.g. `--mobile --device "iPhone 15"`. Also reachable from a config file or env that populates both cliOptions.mobile and cliOptions.device.
Common situations: Copy-pasted flags from an example that used --device into a command that already had --mobile; migration from --device to --mobile without removing the old flag; a wrapper script that sets both unconditionally.
Related errors
- --mobile is not supported with the Firefox browser.
- Device emulation is not supported with cdpEndpoint.
- Invalid resolution format: use ${name}="800x600"
- Invalid ${name}: ${value}. Valid values are: ${options.join(
- Init script file does not exist: ${script}
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/9700a4ab2116e688.
Report an issue: GitHub.