Updated: · Automation Notes admin

Playwright “Executable doesn't exist”: Why It Happens and How to Fix It

A Python Playwright script that had been running automatically every day suddenly stopped, unable to launch the browser. I hadn't changed any code. It was working fine just the day before.

This is an issue I ran into firsthand. The cause was that browser binaries are shared across multiple projects, and actions in another project ended up deleting them. In this article, I'll explain what happened, how to fix it, and how to prevent it from happening again.

What the Error Looked Like

In my environment, the logs showed an error formatted like this (paths have been replaced):

BrowserType.launch: Executable doesn't exist at
C:\path\to\ms-playwright\chromium_headless_shell-XXXX\...\headless_shell.exe

The message also included a suggestion along the lines of "Looks like you just installed or updated Playwright." In my case, however, I hadn't updated that project at all. The real cause was that another project had deleted the browser. I felt it was better not to be misled by this guidance. Note that this specific error message format is what I saw in my environment's logs and is not from the official documentation. The numbers and wording will vary depending on your Playwright version.

Root Cause: Browsers Live in a Shared Folder Outside the venv

In Playwright for Python, after installing the library with pip install playwright, you install the browser binaries separately using playwright install. According to the official documentation, the browser install location on Windows is %USERPROFILE%\AppData\Local\ms-playwright. Because it is not inside the venv, it is shared across all projects for the same user.

Furthermore, the official documentation provides the following explanation:

In other words, when Project A uses an older version of Playwright and Project B uses a newer version, running playwright install in B can cause the older browser required by A to be considered unused and deleted. In my environment, I had only run pip install in A without running playwright install. As a result, A was never recorded as a client using that browser, which I believe caused it to be targeted for deletion.

What Happened

  1. 1. Shared LocationBrowsers are placed outside the venv in ms-playwright, shared across all projects
  2. 2. Update ElsewhereProject B installs a newer version and runs playwright install
  3. 3. Cleaned UpThe older browser version with no active clients is deleted
  4. 4. Project A StopsFails with Executable doesn't exist on the next day's automated run
Project A stops even though neither its code nor its environment was changed.

How to Fix It

Reinstall the browser using the Python executable from the affected project's venv.

"C:\path\to\venv\Scripts\python.exe" -m playwright install chromium

Even without activating the venv, calling python.exe by its full path installs the browser that matches that venv's Playwright version (I also use this technique in A Python venv Inside OneDrive Can Break Your Scheduled Scripts). According to the official documentation, Playwright provides a separate build for headless use (chromium headless shell), and running playwright install chromium installs Chromium.

In my environment, after aligning the Playwright version with my other projects before installing, the existing browser was reused without triggering a download.

Preventing Recurrence

MethodDetailsBest Suited For
Always run install after creating a venvRun python -m playwright install chromium right after pip installSomething everyone should do first. This stopped the issue from happening for me
Isolate the install locationSpecify the same path for installation and runtime using the environment variable PLAYWRIGHT_BROWSERS_PATHWhen you want to keep browsers isolated per project
Disable automatic cleanupSet PLAYWRIGHT_SKIP_BROWSER_GC=1 or pass --no-remove to installWhen you intentionally want to keep older versions
Use installed Edge or ChromeSpecify channel="msedge" or channel="chrome" at launchWhen you do not want to install dedicated Playwright browsers

The official documentation notes that PLAYWRIGHT_BROWSERS_PATH can be used both to install browsers in a custom location and to locate them at runtime. If you isolate them, make sure to specify the same value for both installation and execution.

In the Python version, channel is specified as follows:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(channel="msedge")

According to the official documentation, channel can be set to values such as "chrome" or "msedge". However, the default is the bundled Chromium, and the official documentation says: "Using the default Playwright configuration with the latest Chromium is a good idea most of the time." Keep in mind that installed Edge or Chrome may auto-update, which could change their behavior.

Catching Failures Early in Unattended Runs

When running manually, you see errors immediately. The danger with daily automated runs is that failures can go unnoticed for days. By adding mechanisms such as recording Task Scheduler exit codes or updating a success marker file on each run and sending alerts if it gets too old, you can notice failures the very next day. I cover the general approach in Catch Task Scheduler Failures: Check Your Automated Runs Every Morning. For instructions on configuring tasks, see Run Claude Code Automatically Every Day with Windows Task Scheduler.

Summary