Playwright browser executable doesn't exist: Error: browserType.launch: Executable doesn't exist at
Playwright went to launch the exact browser build its own version pins, and nothing was at that path. No test step ran, so the fix is in how the job installs or locates browsers, not in the spec.
MINIMAL REPRO
Reproduce it
Run on 2026-10-23 with @playwright/test 1.62.1, macOS, arm64. The output below is what it printed.
import { defineConfig } from "@playwright/test"
export default defineConfig({ testDir: "./tests" })import { test, expect } from "@playwright/test"
test("browser launches", async ({ page }) => {
await page.setContent("<h1>ok</h1>")
await expect(page.getByRole("heading")).toHaveText("ok")
})PLAYWRIGHT_BROWSERS_PATH="$PWD/empty" npx playwright test --reporter=list# <scratch> is the run's working directory, shortened here
✘ 1 tests/launch.spec.ts:3:5 › browser launches (1ms)
Error: browserType.launch: Executable doesn't exist at <scratch>/empty/chromium_headless_shell-1234/chrome-headless-shell-mac-arm64/chrome-headless-shell
╔════════════════════════════════════════════════════════════╗
║ Looks like Playwright was just installed or updated. ║
║ Please run the following command to download new browsers: ║
║ ║
║ npx playwright install ║
║ ║
║ <3 Playwright Team ║
╚════════════════════════════════════════════════════════════╝RANKED DIAGNOSIS
What usually causes it
- 01
The browsers were never installed in this job
Installing @playwright/test from npm gives you the runner, not the browsers: none of the Playwright packages has an install script that downloads them. Playwright's browser guide says each version needs specific browser binaries and that you install them with the Playwright CLI. A fresh runner that only ran npm ci has nothing at the path.
DIAGNOSE
Run `npx playwright install --dry-run chromium` in the failing job. It prints the build this version expects (chromium-headless-shell v1234 for 1.62.1) and its install location. List that directory.
FIX
Add `npx playwright install --with-deps chromium` after the dependency install and before the tests, in the same job and as the same user.
- 02
A cache or Docker image was built for another Playwright version
The directory name carries the build number, so browsers installed for one release are invisible to the next. We pointed 1.62.1 at a browsers path holding only build 1228 and it still asked for chromium_headless_shell-1234. A restored ms-playwright cache keyed on anything but the Playwright version does the same, and so does an mcr.microsoft.com/playwright image whose tag differs from the project's version.
DIAGNOSE
Compare the build number in the error path with the directories in the browsers path. In a container, compare the image tag with `npx playwright --version`.
FIX
Pin the image tag to the exact Playwright version in the lockfile. If you cache browsers at all, key the cache on that version. Playwright's CI guide advises against caching them, because a restore takes about as long as a download.
- 03
Install and run see different browser paths
The default location sits under the user's home directory (~/.cache/ms-playwright on Linux, ~/Library/Caches/ms-playwright on macOS), and PLAYWRIGHT_BROWSERS_PATH overrides it. Installing as root in a Dockerfile and running as another user, or exporting the variable in one step only, sends the launch to an empty directory. That is exactly what the repro does on purpose.
DIAGNOSE
Print HOME, the effective user and PLAYWRIGHT_BROWSERS_PATH in both the install step and the test step.
FIX
Set PLAYWRIGHT_BROWSERS_PATH once, at job or image level, or install as the user that runs the tests.
- 04
Only the headless shell was installed, and the run needs full Chromium
`--only-shell` skips the full Chromium download for jobs that only run headless. A headed run, or a project using the 'chromium' channel for Chromium's new headless mode, needs the chromium-<build> directory instead. With only chromium_headless_shell-1234 present, our spec passed headless and failed under --headed with Executable doesn't exist at …/chromium-1234/….
DIAGNOSE
Read the missing path: chromium_headless_shell-<build> and chromium-<build> are different installs.
FIX
Drop --only-shell, or use it only in jobs that never run headed or with the 'chromium' channel.
VERIFIED FIX
The fix, and how it was checked
Install the browser build that matches the Playwright version, in the job and as the user that runs the tests.
- run: npm ci
- run: npx playwright install --with-deps chromium
- run: npx playwright testRe-run on 2026-10-23 with @playwright/test 1.62.1 on macOS, arm64: `npx playwright install --dry-run chromium` named chromium-headless-shell v1234 under ~/Library/Caches/ms-playwright, and with PLAYWRIGHT_BROWSERS_PATH unset the same spec printed 1 passed (496ms). A browsers path holding only chromium_headless_shell-1228 still asked for the 1234 directory, and a path holding only the 1234 headless shell passed headless and failed under --headed. The workflow steps above follow Playwright's CI guide; they were not run on a hosted runner.
When this is not the cause
- Missing Linux libraries
- When the executable exists but its shared libraries do not, Playwright 1.62.1 reports Host system is missing dependencies to run browsers instead. That is the --with-deps half of the install, and a different error.
- The test, its timeout or its locators
- browserType.launch throws before the first test step; the repro failed in 1 ms. No change to the spec or to timeouts can affect it.
- A broken node_modules
- Deleting node_modules and running npm ci again reinstalls the runner and leaves the browsers directory exactly as it was.
Prevent the repeat
- →Install browsers in the job that runs the tests, with the version from the lockfile.
- →Keep the Playwright Docker image tag and the npm version in one place and bump them together.
- →Fail fast with `npx playwright install --dry-run` output in the log when a launch fails.
Run this against your evidence
The browser triage workflow uses the same stable pattern slug and does not upload your paste.