QA How-To
How to Fix Playwright browserType.launch executable does not exist
Fix Playwright browserType.launch executable does not exist by aligning package versions, browser installs, cache paths, CI steps, containers, and proxies.
24 min read | 3,496 words
TL;DR
To fix Playwright browserType.launch executable does not exist, run your locked package install, then run `npx playwright install` for the browser you execute. In Linux CI use `npx playwright install --with-deps chromium` or a Playwright container image that matches your package version, and make sure installation and test execution use the same `PLAYWRIGHT_BROWSERS_PATH`, user, working tree, and Playwright version.
Key Takeaways
- Install browsers with the Playwright CLI resolved from the same locked dependency tree that runs the tests.
- Reinstall browser binaries after upgrading Playwright because each release expects specific browser revisions.
- Keep PLAYWRIGHT_BROWSERS_PATH identical during installation and execution, especially across CI steps and container users.
- On Linux, install both the browser and required operating system libraries with the supported CLI or matching container image.
- Treat browser cache restoration as an optimization, never as a replacement for a deterministic install step.
- Match the Playwright container image tag to the package version and avoid unreviewed custom executable paths.
- Use executablePath(), install --list, lockfile inspection, and file checks to identify version or path mismatches quickly.
To fix playwright browserType.launch executable does not exist, install the browser binary expected by the Playwright package that actually runs your test. In a Node.js project, the usual repair is npm ci followed by npx playwright install, or npx playwright install --with-deps chromium on a fresh Linux runner.
The command alone is not always enough. The error can persist when the install and test use different Playwright versions, cache roots, operating system users, container layers, or package workspaces. This guide shows how to identify that mismatch, make the install deterministic, and prevent the failure from returning in CI.
TL;DR
| Situation | Correct first action | Why it works |
|---|---|---|
| Fresh local checkout | npm ci && npx playwright install |
Installs binaries for the locked package version |
| Linux CI without a browser image | npx playwright install --with-deps chromium |
Adds the browser plus required OS libraries |
| Playwright was upgraded | Re-run npx playwright install |
A new package can require a new browser revision |
| Shared custom cache | Use the same PLAYWRIGHT_BROWSERS_PATH for install and test |
Prevents lookup in a different directory |
| Docker image | Match the image tag to the installed Playwright version | Keeps bundled browsers and package expectations aligned |
| Corporate network | Configure HTTPS_PROXY or approved certificates for the install step |
Allows the browser archive to download and verify |
Do not copy a random browser executable into the path from the message. Restore the package-to-browser contract so updates and CI runs remain repeatable.
1. What the Error Actually Means
The failure normally contains a path and guidance similar to this:
browserType.launch: Executable doesn't exist at <expected-path>
chromium.launch(), firefox.launch(), and webkit.launch() start browser builds managed by Playwright. Each Playwright release expects specific browser revisions. The Node package contains the client and registry metadata, while browser binaries live in an operating system cache or a configured shared or hermetic path. If the expected executable is absent, browserType.launch() cannot start.
This is different from a browser process that starts and immediately crashes. A missing shared Linux library can produce a launch failure, but the executable exists. A navigation timeout occurs after launch. Read the first line and the expected path before applying a fix.
The error often appears after a dependency update because the package now expects a different revision than the one left in the cache. It also appears in clean CI because npm ci installs JavaScript dependencies but a separate browser installation step is still required. Other common triggers are clearing caches, setting PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD, changing users, moving between an Intel and Arm machine, or restoring a cache created for another operating system.
Playwright's message is diagnostic evidence. Record the exact path, browser name, installed package version, CLI version, operating system, architecture, and the command that ran. Those facts quickly separate a missing install from a version or environment mismatch.
2. Root-Cause Decision Table
Use the surrounding evidence instead of reinstalling repeatedly. The following reference table maps common patterns to the most likely cause.
| Evidence | Likely cause | Targeted fix |
|---|---|---|
Fails immediately after npm ci on a clean agent |
Browser install step is missing | Run the Playwright CLI install after dependency installation |
| Started after dependency upgrade | Cached revision belongs to older Playwright | Install browsers using the upgraded locked CLI |
| CLI install succeeds but tests look elsewhere | Browser path environment differs | Align PLAYWRIGHT_BROWSERS_PATH and execution user |
| Works on host, fails in container | Browser was installed outside the final image or for another user | Install in the final runtime image or use a matching Playwright image |
| Chromium works, WebKit fails | Only selected browser was installed | Install WebKit or limit projects intentionally |
| Download never completes | Proxy, certificate, or network restriction | Configure approved proxy, CA, mirror, or prebuilt artifact flow |
| Executable exists, launch still fails | OS dependency, permission, architecture, or sandbox issue | Diagnose the new launch error rather than the missing-file error |
| Monorepo root command installs wrong revision | Different workspace resolves the CLI | Run from the test package and use its lockfile |
Do not confuse the Playwright Test package, the playwright library package, and playwright-core. @playwright/test and playwright expose the CLI used for browser installation. playwright-core does not download browsers by itself. In a mixed dependency tree, npx resolution and the importing test package must agree.
The Playwright timeout troubleshooting guide is relevant only after the browser starts. This error happens before page actions or assertions can run.
3. Fastest way to fix playwright browserType.launch executable does not exist
From the package directory that owns the Playwright tests, restore dependencies from the committed lockfile and install the browsers used by configured projects:
npm ci
npx playwright install
npx playwright test
Installing every supported browser is simple but may be unnecessary. If the suite runs Chromium only, install only Chromium:
npm ci
npx playwright install chromium
npx playwright test --project=chromium
On a Linux machine or fresh CI image that also lacks native libraries, use:
npm ci
npx playwright install --with-deps chromium
npx playwright test --project=chromium
Run npx playwright --version before and after the install when you suspect resolution problems. The command should report the version from the project dependency, not a stale global installation. Avoid sudo npx playwright install followed by unprivileged test execution. That can place files under another user's cache and create permissions or lookup differences. Use elevated permissions only for the operating system dependency step when your environment explicitly requires it.
Do not solve a local missing browser by installing an unrelated system Chromium package and hoping Playwright discovers it. Default launch expects Playwright's managed build. A branded Chrome project is configured with a channel, and a custom executable is an explicit advanced choice.
After the repair, remove any emergency executable path override you added during diagnosis. The ordinary managed-browser path is more portable across machines and upgrades.
4. Align the Package Manager, Lockfile, and CLI
The browser installer must come from the same dependency graph as the tests. A repository may contain npm, pnpm, or Yarn workspaces, multiple lockfiles, or several Playwright packages. Running a command at the wrong level can resolve a different version.
For npm, use the committed package-lock.json:
npm ci
npx playwright --version
npm ls @playwright/test playwright playwright-core
npx playwright install chromium
For pnpm or Yarn, use the repository's pinned package-manager command and immutable install mode. The principle is the same: restore the lockfile exactly, invoke the local Playwright CLI, install the required browser, then run the same workspace's suite. Do not switch package managers only to repair the binary.
In a monorepo, make the working directory explicit in CI:
- name: Install workspace dependencies
working-directory: apps/e2e
run: npm ci
- name: Install the locked Chromium build
working-directory: apps/e2e
run: npx playwright install --with-deps chromium
- name: Run browser tests
working-directory: apps/e2e
run: npx playwright test --project=chromium
If Playwright is hoisted at the root, install and execute from the root according to the workspace design. The important point is consistency, not a particular folder.
After any Playwright version change, rerun the browser install locally and in image builds. Keep the package lock and container definition in the same review so a reviewer can see whether the expected browser revision will exist.
5. Diagnose the Expected Executable and Cache Path
Use supported APIs and ordinary file checks to see where the resolved package expects its browser. This Node.js script is runnable after installing playwright or @playwright/test and a Chromium browser:
import { access } from 'node:fs/promises';
import { chromium } from '@playwright/test';
const expected = chromium.executablePath();
console.log({ expected, browsersPath: process.env.PLAYWRIGHT_BROWSERS_PATH ?? '(default)' });
try {
await access(expected);
console.log('Executable exists');
} catch {
console.error('Executable is missing');
process.exitCode = 1;
}
browserType.executablePath() returns the path where that package expects its bundled executable. It does not install the browser. Compare its result under the same user, working directory, environment variables, and container that runs the failing test.
The default browser cache is operating-system specific. Common roots are %USERPROFILE%\AppData\Local\ms-playwright on Windows, ~/Library/Caches/ms-playwright on macOS, and ~/.cache/ms-playwright on Linux. Do not hard-code those defaults into tests. Home directories, service accounts, and container users can change them.
You can also inspect the managed inventory:
npx playwright install --list
npx playwright --version
If the reported version and expected executable path do not correspond to the dependency you intended, inspect duplicate packages and workspace resolution. If the path is correct but absent, install that browser. If it exists but is not executable, inspect ownership, permissions, filesystem mount options, and architecture.
6. Use PLAYWRIGHT_BROWSERS_PATH Correctly
PLAYWRIGHT_BROWSERS_PATH changes where managed browser binaries are installed and found. It is useful for shared CI caches or controlled developer images, but it creates a contract: the value must be consistent during installation and execution.
A POSIX shell example uses the same value for both commands:
export PLAYWRIGHT_BROWSERS_PATH=$HOME/pw-browsers
npx playwright install chromium
npx playwright test --project=chromium
In PowerShell:
$Env:PLAYWRIGHT_BROWSERS_PATH=Join-Path $Env:USERPROFILE 'pw-browsers'
npx playwright install chromium
npx playwright test --project=chromium
Setting the variable in one CI step may not persist into the next, depending on the runner. Define it at the job level or repeat it explicitly. Also ensure both steps run as the same user and mount the same volume. A shared directory created by root but read by a non-root runtime user is a common source of confusing failures.
For a hermetic local installation, PLAYWRIGHT_BROWSERS_PATH=0 places supported browser assets under the Playwright package's local browser directory. This can suit packaged artifacts, but pruning or reinstalling node_modules removes the assets. Do not cache node_modules blindly as a substitute for a package install.
A custom path must be keyed by operating system, architecture, and the lockfile or Playwright version. Never restore a macOS cache onto Linux or an x64 cache onto an Arm runner. A restored directory can exist and still contain the wrong revision or binary shape.
7. Prevent the Error in CI Pipelines
A deterministic CI job has three ordered phases: install JavaScript dependencies, install the required Playwright browsers and native dependencies, then execute tests. Cache restoration may accelerate the second phase, but the install command should validate and complete the required state.
A concise GitHub Actions job is:
name: Playwright tests
on:
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v6
with:
node-version: lts/*
cache: npm
- run: npm ci
- run: npx playwright install --with-deps chromium
- run: npx playwright test --project=chromium
The Node package cache and the Playwright browser cache are different. actions/setup-node can cache package-manager downloads, but that does not guarantee the browser executable exists. Keep the browser install command.
If you add browser caching, derive the key from runner OS, architecture, and the dependency lock. Treat a hit as an optimization and still run npx playwright install chromium. The installer can reuse an existing correct revision and fetch what is missing. Cache upload and restore paths must match the user that runs tests.
Preserve the first failure's install log and npx playwright --version output. CI-only debugging is far easier when the artifact shows which dependency and cache were selected. The GitHub Actions for Playwright guide covers broader reporting, sharding, and artifact choices.
8. How to fix playwright browserType.launch executable does not exist in Docker
A Playwright Docker image includes browser builds and operating system dependencies, but it does not remove the need to install your project's Node packages. More importantly, the image's Playwright version must match the version used by the project. If they differ, the client can search for a revision that the image does not contain.
Use a versioned image tag that matches the lockfile. Represent the version as a build argument so dependency updates and image updates are reviewed together:
ARG PLAYWRIGHT_IMAGE=mcr.microsoft.com/playwright:v1.61.0-noble
FROM ${PLAYWRIGHT_IMAGE}
WORKDIR /work
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
CMD npx playwright test
The version above is an illustrative current format. In your repository, use the exact version resolved by the lockfile and an officially published matching image tag. Do not use a floating image tag for reproducible tests.
If you build your own base image, install browsers in a layer that survives into the final runtime stage. Multi-stage builds often install the browser in the builder and copy only application files to the final stage. The final image then has the Node package but not the browser cache. Either run npx playwright install --with-deps in the final stage or copy the complete managed browser path with correct ownership and compatible system libraries.
Check the runtime user. Installing to /root/.cache/ms-playwright during build and running as pwuser makes the default lookup point somewhere else. A job-level PLAYWRIGHT_BROWSERS_PATH or the official image's layout can keep the path explicit. For more container design detail, see Docker patterns for browser testing.
9. Install Linux Dependencies Without Masking the Error
On Linux, a browser needs shared libraries in addition to its executable. npx playwright install --with-deps chromium installs the selected browser and supported dependencies on compatible distributions. npx playwright install-deps chromium installs only the system dependencies.
Choose the command based on the actual state:
# Browser plus native dependencies
npx playwright install --with-deps chromium
# Native dependencies only, when the browser is already managed correctly
npx playwright install-deps chromium
If the executable does not exist, install-deps alone cannot fix it. If the executable exists but the process reports missing libraries, repeatedly downloading the browser cannot fix the operating system. Preserve the exact error after the first issue is resolved because one missing layer can expose the next.
Minimal Linux distributions and unsupported base images can require more care. Prefer an officially supported distribution or Playwright's maintained container image. Copying an executable from another distribution may fail because its linked libraries and architecture differ.
Container security settings can also affect launch, but they produce different evidence from a missing file. Do not add --no-sandbox or broad privileges as a reflex. Follow the supported container guidance, use a non-root user where appropriate, and review the isolation model for untrusted sites. The target is a browser that exists, has its native libraries, and runs under an intentional security configuration.
10. Handle Proxies, Certificates, and Restricted Networks
When the install command cannot reach the browser download service, the later launch error is only a symptom. Preserve the installation output. It may show a proxy refusal, certificate-chain error, DNS failure, download timeout, or blocked host.
Configure an approved HTTPS proxy for the install process:
HTTPS_PROXY=https://proxy.example.test:8443 npx playwright install chromium
If corporate TLS inspection uses a private certificate authority, point Node to the approved CA bundle:
export NODE_EXTRA_CA_CERTS=/etc/company/ca.pem
npx playwright install chromium
Use real organization-managed values, protect credentials, and do not disable certificate verification. PowerShell and Windows command shells require their own environment-variable syntax.
Organizations can configure an internal artifact host with Playwright's supported download-host variables. Mirror governance must ensure the exact requested archives are synchronized and integrity is maintained. A stale mirror can make one package version install while a newer revision fails.
For isolated networks, build and scan a versioned base image or browser artifact in an approved connected pipeline, then promote it through the same artifact system as other dependencies. Record Playwright version, browser revisions, OS, architecture, and checksum provenance. Do not copy a developer's cache manually into production CI because it is difficult to audit and easy to mismatch.
11. Know When to Use Channels or executablePath
Playwright can run branded browsers through channels such as chrome or msedge, and browserType.launch() accepts an executablePath option. These are intentional configurations, not general repairs for a missing managed browser.
A project that explicitly tests installed Google Chrome can use a supported channel:
import { defineConfig } from '@playwright/test';
export default defineConfig({
projects: [
{
name: 'Google Chrome',
use: { channel: 'chrome' },
},
],
});
The environment must actually have that branded browser installed. The Playwright CLI can install supported branded channels on appropriate systems, but organization policy may prefer managed system installation.
Use executablePath only when you own the compatibility risk and have a concrete reason, such as testing a controlled browser build. Playwright works best with its bundled revisions, and arbitrary executables may differ in protocol behavior, codecs, policies, or command-line support. Validate the path, version, architecture, permissions, and update process.
Do not set executablePath: chromium.executablePath() as a workaround. Default chromium.launch() already uses the managed expected path. If that path is missing, explicitly passing it changes nothing. Install the correct revision or fix the cache lookup.
12. Special Cases: Monorepos, Serverless Hosts, and Remote Browsers
Monorepos can contain multiple Playwright consumers. Centralize the dependency if practical, or ensure each test package installs the browsers its locked version expects. A shared cache can hold multiple revisions, but the cache key, garbage collection behavior, and install commands must remain predictable. Run npm ls from the failing workspace to find unexpected duplicates.
Some serverless and edge execution environments do not support launching a full browser process or do not provide writable persistent storage. Installing a browser at request time is usually too large, slow, or restricted. The correct architecture may be a dedicated test runner, a compatible browser service, or a containerized job, not another path override. Confirm platform process, filesystem, memory, and binary limits.
For remote browsers, browserType.connect() attaches to a Playwright browser server, while connectOverCDP() is a Chromium-specific lower-fidelity connection option. A client that connects remotely does not need to launch a local managed browser for that path, but client and server compatibility still matters. Do not switch to a remote browser merely to avoid fixing a broken local CI image unless remote execution is an intentional design choice.
Also distinguish package installation from application deployment. Browser-based tests often belong in the pipeline that validates the deployed application, not inside the web server runtime image. Keeping test execution in a dedicated job reduces production image size and gives the runner the permissions and dependencies it needs.
13. Verify the Repair and Make It Reproducible
A repair is complete when it works from a clean state in the environment that failed. First, print the resolved version and expected path. Then run a minimal launch test before the full suite:
import { test, expect } from '@playwright/test';
test('managed Chromium launches', async ({ page, browserName }) => {
await page.setContent('<h1>Browser ready</h1>');
await expect(page.getByRole('heading', { name: 'Browser ready' })).toBeVisible();
expect(browserName).toBe('chromium');
});
Execute it with the intended project:
npx playwright test tests/browser-ready.spec.ts --project=chromium
Then rebuild the container without relying on an untracked local layer, or rerun CI from a clean agent. Verify the install step, runtime user, environment variables, cache key, and package version in logs. If a browser cache is restored, test one run with that cache disabled to prove the installation procedure is sufficient.
Document the rule near pipeline code: browser installation follows the locked Node dependency installation, image and package versions move together, and only configured projects are installed. Add dependency-update automation that changes both artifacts in one pull request when possible.
Finally, remove stale global Playwright assumptions from team instructions. Developers should use the repository CLI through npx or the pinned package-manager equivalent. Reproducibility comes from the repository's lockfile and pipeline, not from whatever browser happens to exist on one workstation.
Interview Questions and Answers
Q: Why does Playwright say the browser executable does not exist after npm install?
The Node dependency and managed browser binary are separate installation concerns. A clean environment must run the Playwright browser install command for the resolved package version. On Linux it may also need native dependencies.
Q: Why can the error appear after upgrading Playwright?
Each release can expect new browser revisions. The old cache may be valid for the previous package but not contain the path requested by the new one, so browser installation must follow the dependency update.
Q: How would you debug this only in CI?
I would capture the expected path from executablePath(), CLI version, dependency tree, user, OS, architecture, and PLAYWRIGHT_BROWSERS_PATH. Then I would compare the install and test steps for different users, workspaces, images, or cache roots.
Q: What does --with-deps add?
It installs the selected Playwright browser and the required operating system dependencies on supported Linux environments. It addresses both the browser archive and native library layer in one command.
Q: Should browser binaries be cached in CI?
They can be cached as an optimization if the key includes OS, architecture, and the locked dependency state. I still run the supported install command so a missing or stale cache is completed deterministically.
Q: Why must a Playwright Docker image match the package version?
The image contains browser revisions for its tagged Playwright release, while the project package decides which revision to launch. A mismatch can make the client request an executable that is not present in the image.
Q: When would you use a custom executablePath?
Only when the test intentionally targets a controlled custom browser and the team owns compatibility, updates, and support. It is not my default fix for a missing managed binary.
Q: What is the difference between a missing executable and missing Linux dependencies?
A missing executable fails because the expected file is absent. Missing dependencies fail after the binary is found and the operating system cannot load required libraries, so the evidence and repair are different.
Common Mistakes
- Running
npm cibut omittingnpx playwright installon a clean runner. - Invoking a global or different-workspace CLI than the package that runs tests.
- Upgrading Playwright without installing its new managed browser revisions.
- Installing as root and executing as another user with a different home directory.
- Setting
PLAYWRIGHT_BROWSERS_PATHfor install but not for test execution. - Restoring a browser cache across different operating systems or architectures.
- Using
install-depswhen the executable itself is absent. - Using a Docker image whose tag does not match the locked package version.
- Adding an arbitrary
executablePathinstead of fixing the managed install. - Hiding proxy or certificate failures by discarding browser-install logs.
- Copying only Node modules from a multi-stage build while leaving the browser cache behind.
- Assuming a retry can repair immutable missing infrastructure.
Conclusion
To fix playwright browserType.launch executable does not exist reliably, align four things: the locked Playwright package, the installed browser revision, the runtime operating system, and the browser lookup path. Install dependencies first, run the local Playwright CLI for the browsers you execute, and include native dependencies on fresh Linux hosts.
Then reproduce the repair from a clean runner or image. Keep install and test steps under the same user and cache configuration, match container and package versions, and preserve install diagnostics. That turns a one-time workstation fix into a stable build contract.
Interview Questions and Answers
What causes browserType.launch executable does not exist?
The resolved Playwright client expects a managed browser file that is absent from its lookup path. Common reasons are a skipped browser install, a package upgrade, a different cache root or user, a workspace version mismatch, or a container layer that omitted the browser.
What is your first repair command on a clean Linux CI agent?
After restoring locked Node dependencies, I run `npx playwright install --with-deps` for the exact browsers configured in the suite. I then execute a minimal launch test before the full regression when diagnosing the image.
How do you prove the installer and runner use the same Playwright version?
I run the local CLI from the test package, print `npx playwright --version`, and inspect the dependency tree with the package manager. In a monorepo I also make the working directory explicit.
How do you investigate a PLAYWRIGHT_BROWSERS_PATH issue?
I print the variable and `browserType.executablePath()` during the failing runtime, then compare them with the install step's user, environment, and mounted volumes. Both phases must point to the same compatible cache.
Would you cache Playwright browsers?
Yes, only as a measured optimization. I key the cache by OS, architecture, and locked Playwright state, and still execute the supported install command so a miss or stale entry is repaired.
Why is using a random system Chromium risky?
Playwright is tested with its bundled browser revisions. An arbitrary build can differ in protocol behavior, features, codecs, policies, or launch arguments, so failures become harder to reproduce and support.
How do multi-stage Docker builds cause this failure?
The builder stage may install the browser into its own cache, while the final stage copies only the application and Node packages. The runtime package then expects a binary that was never copied or installed in the final filesystem.
How is this error different from a Playwright timeout?
The missing executable prevents browser launch entirely, so no page or locator operation starts. A timeout occurs after an operation begins and requires synchronization, application, or performance diagnosis rather than browser provisioning.
Frequently Asked Questions
How do I fix browserType.launch executable doesn't exist in Playwright?
Install project dependencies from the lockfile, then run `npx playwright install` for the required browser. On a clean Linux runner, use `npx playwright install --with-deps chromium` when the suite uses Chromium.
Why did the Playwright executable disappear after an update?
The updated package may expect a different browser revision and path. Re-run the browser install command using the CLI resolved from the updated locked dependency tree.
Where does Playwright install browser binaries?
By default it uses an operating-system cache under the current user's profile. You can configure a shared location with `PLAYWRIGHT_BROWSERS_PATH` or use hermetic installation with the value `0`, but install and execution must use the same setting.
Does npm install download Playwright browsers?
Do not rely on the package installation to provision browsers. Make the browser step explicit with `npx playwright install`, which ensures clean developer and CI environments receive the revisions required by the installed package.
What is the difference between playwright install and install-deps?
`playwright install` downloads managed browser builds. `playwright install-deps` installs supported operating system libraries, while `playwright install --with-deps` performs both jobs.
Why does Playwright work locally but report a missing executable in Docker?
The host browser cache is not automatically part of the container. Install the browser in the final image or use an official Playwright image whose version matches the project package, and check the runtime user and browser path.
Can I fix the missing browser by setting executablePath to system Chrome?
You can intentionally run a controlled custom executable, but it carries compatibility risk and is not the normal repair. Prefer installing Playwright's managed revision or configure a supported branded browser channel when that is the real test requirement.
Related Guides
- How to Fix Playwright element is not visible
- How to Fix Playwright locator resolved to hidden element
- How to Fix Playwright waiting for element to be visible enabled and stable
- How to Fix Playwright element is outside of the viewport
- How to Fix Playwright Execution context was destroyed
- How to Fix Playwright expect received value must be a Locator