How to fix Playwright "Executable doesn't exist" after install?
PlaywrightThe "Executable doesn't exist" error means the @playwright/test package is installed but the corresponding browser binaries were not downloaded to the expected location. Playwright stores browser binaries separately from the npm package, in a cache directory (~/.cache/ms-playwright on Linux/macOS, %LOCALAPPDATA%\ms-playwright on Windows). When the cache doesn't exist — typically in a fresh CI environment, a Docker image that didn't include the install step, or after upgrading the Playwright version without reinstalling browsers — tests fail immediately at launch time.
Common mistake
# Only installs the npm package — no browser binaries
npm install @playwright/test
# Tries to launch but Chromium doesn't exist
npx playwright test
Also common in Docker:
FROM node:20 WORKDIR /app COPY package.json . RUN npm install # Missing: browser and OS deps installation COPY . . CMD ["npx", "playwright", "test"]
The fix
Always run the browser install step after package installation:
# Install Playwright package
npm install @playwright/test
# Install browsers only
npx playwright install
# Install browsers AND OS-level dependencies (required on most Linux CI images)
npx playwright install --with-deps
For Docker, use the official Playwright base image or install dependencies explicitly:
# Option 1: Use the official Playwright image (recommended) FROM mcr.microsoft.com/playwright:v1.44.0-jammy WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci COPY . . CMD ["npx", "playwright", "test"]
# Option 2: Start from Node and install Playwright dependencies FROM node:20-bookworm-slim WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci RUN npx playwright install --with-deps chromium COPY . . CMD ["npx", "playwright", "test"]
For GitHub Actions, cache the browser binaries to avoid downloading them on every run:
- name: Install dependencies
run: npm ci
- name: Cache Playwright browsers
uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: playwright-${{ hashFiles('package-lock.json') }}
- name: Install Playwright browsers
run: npx playwright install --with-deps
Why it works
Playwright separates the test runner (npm package) from the browser binaries (downloaded separately) because browser binaries are large (~100–300 MB each) and version-pinned to the Playwright release. When you upgrade @playwright/test, the binary paths change and previously cached binaries are no longer at the expected location. Running npx playwright install after any version change downloads exactly the binary versions the current package expects. The --with-deps flag additionally installs the Linux shared libraries (glibc, nss, fonts, etc.) that Chromium requires to launch.
Tips
- Add npx playwright install --with-deps as a step in every CI pipeline, not just the first run — version upgrades require it.
- Pin both the @playwright/test version in package.json and the Docker base image tag together to avoid binary path mismatches.
- If you only need Chromium and want to reduce install time, use npx playwright install --with-deps chromium instead of installing all three browsers.
- After upgrading Playwright, run npx playwright install locally too — your local cache may have the old binary paths.