microsoft/playwright · error · Error

Only one of --no-shell and --only-shell can be specified

Error message

Only one of --no-shell and --only-shell can be specified

What it means

Thrown by the `playwright install` command when both --no-shell (skip installing shell/python bindings) and --only-shell (install ONLY shell bindings) are passed. The flags describe mutually exclusive install scopes, so the second condition (`options.shell === false && options.onlyShell`) makes the intent ambiguous.

Source

Thrown at packages/playwright-core/src/cli/installActions.ts:114

      `installing your project's dependencies.`,
      ``,
      `To avoid unexpected behavior, please install your dependencies first, and`,
      `then run Playwright's install command:`,
      ``,
      `    npm install`,
      `    npx playwright install`,
      ``,
      `If your project does not yet depend on Playwright, first install the`,
      `applicable npm package (most commonly @playwright/test), and`,
      `then run Playwright's install command to download the browsers:`,
      ``,
      `    npm install @playwright/test`,
      `    npx playwright install`,
      ``,
    ].join('\n'), 1));
  }
  if (options.shell === false && options.onlyShell)
    throw new Error(`Only one of --no-shell and --only-shell can be specified`);
  const shell = options.shell === false ? 'no' : options.onlyShell ? 'only' : undefined;
  const executables = registry.resolveBrowsers(args, { shell });
  if (options.withDeps)
    await registry.installDeps(executables, !!options.dryRun);
  if (options.dryRun && options.list)
    throw new Error(`Only one of --dry-run and --list can be specified`);
  if (options.dryRun) {
    for (const executable of executables) {
      console.log(registry.calculateDownloadTitle(executable));
      console.log(`  Install location:    ${executable.directory ?? '<system>'}`);
      if (executable.downloadURLs?.length) {
        const [url, ...fallbacks] = executable.downloadURLs;
        console.log(`  Download url:        ${url}`);
        for (let i = 0; i < fallbacks.length; ++i)
          console.log(`  Download fallback ${i + 1}: ${fallbacks[i]}`);
      }
      console.log(``);
    }

View on GitHub (pinned to c8fc3bf8d3)

Solutions

  1. Pick one scope: `npx playwright install --only-shell` to install shell bindings only.
  2. Or `npx playwright install --no-shell` to install browsers without shell bindings.
  3. Audit CI/playwright install invocations for duplicated/contradictory flags.

Example fix

// before
npx playwright install --no-shell --only-shell
// after
npx playwright install --only-shell
Defensive patterns

Strategy: validation

Validate before calling

if (args.includes('--no-shell') && args.includes('--only-shell'))
  throw new Error('Choose one: --no-shell OR --only-shell');

Prevention

When it happens

Trigger: Running `npx playwright install --no-shell --only-shell`, or a wrapper script/CI matrix that concatenates both flags. The check fires only when --no-shell is explicitly false-set and --only-shell is truthy together.

Common situations: Cargo-culted install scripts in CI YAML that accumulate flags over time, or shell aliases that hardcode one flag while a developer adds the other on the command line.

Related errors


AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12). Data as JSON: /api/errors/a4ea991751e30757. Report an issue: GitHub.