Executable doesn't exist at /root/.cache/ms-playwright/chromium-1200/chrome-linux64/chrome

My application is playwright. I got

browser = await playwright.chromium.launch(headless=False)
File “/usr/local/lib/python3.10/site-packages/playwright/async_api/_generated.py”, line 14549, in launch
await self._impl_obj.launch(
File “/usr/local/lib/python3.10/site-packages/playwright/_impl/_browser_type.py”, line 98, in launch
await self._channel.send(
File “/usr/local/lib/python3.10/site-packages/playwright/_impl/_connection.py”, line 69, in send
return await self._connection.wrap_api_call(
File “/usr/local/lib/python3.10/site-packages/playwright/_impl/_connection.py”, line 559, in wrap_api_call
raise rewrite_error(error, f"{parsed_st[‘apiName’]}: {error}") from None
playwright._impl._errors.Error: BrowserType.launch: Executable doesn’t exist at /root/.cache/ms-playwright/chromium-1200/chrome-linux64/chrome

At the bottom, it has the following hint

Looks like Playwright was just installed or updated. ║
║ Please run the following command to download new browsers: ║
║ ║
║ playwright install ║
║ ║
║ <3 Playwright Team

I can follow the instruction of install selenium in Gradio if that will help. Please advise.

1 Like

Chromium binary is missing?


This error means Playwright’s Python code is present, but the Chromium binary Playwright expects is not present at runtime.

Playwright does not drive your system Chrome by default. It downloads and manages its own browser builds (Chromium, Firefox, WebKit) into a cache folder named ms-playwright. On Linux that default cache is ~/.cache/ms-playwright, so if you are running as root it becomes /root/.cache/ms-playwright. (Playwright)

Your path includes chromium-1200/.../chrome. That chromium-1200 folder is the specific pinned browser build Playwright expects for the version you are running. If the folder is missing, Playwright fails exactly like your traceback.


Background: how Playwright installs actually work

There are two separate installs:

  1. Install the library (Python package)
  2. Install the browser binaries (Chromium, etc.) into ms-playwright

Playwright’s Python docs explicitly call out the browser install commands and the dependency install commands. (Playwright)

Also, Playwright caches browsers in folders like chromium-XXXXXX, firefox-XXXX, webkit-XXXX. (Playwright)


The most common causes (with context)

Cause 1: You installed/updated Playwright but never downloaded browsers

Typical when you run only pip install playwright (or your platform installs requirements) and you never run the browser installer.

Fix

python -m playwright install chromium
# or install all default browsers
python -m playwright install

Playwright documents playwright install and “install a specific browser” forms. (Playwright)

Why python -m playwright is often better: it reduces “wrong CLI on PATH” mistakes in multi-venv/container setups.


Cause 2: Build-time vs run-time mismatch (Docker, CI, PaaS, Gradio deployments)

You downloaded browsers in one place, then ran the app somewhere else:

  • different user (root at build time, non-root at runtime)
  • different filesystem (ephemeral runtime, different container layer)
  • different cache location

Playwright’s own docs say the default Linux cache is ~/.cache/ms-playwright. If the runtime user is different, that path changes. (Playwright)

Fix patterns

  • Install browsers in the same image stage that runs the app.
  • Run as a consistent user.
  • Or set a consistent shared path via PLAYWRIGHT_BROWSERS_PATH. (Playwright)

Example Dockerfile pattern:

RUN pip install playwright \
 && python -m playwright install --with-deps chromium

The --with-deps combo is documented. (Playwright)


Cause 3: Linux system dependencies missing

This does not usually produce “executable doesn’t exist” first, but it is the next common failure after you install browsers.

Playwright provides:

  • playwright install-deps
  • or playwright install --with-deps chromium (one step) (Playwright)

Fix

python -m playwright install --with-deps chromium
# or:
python -m playwright install-deps
python -m playwright install chromium

Documented in the Python “Browsers” page and CI guide. (Playwright)


Cause 4: Your environment blocks browser downloads (proxy, firewall, custom CA)

If playwright install silently fails during build, you later see the “executable doesn’t exist” error at runtime.

Playwright documents:

  • HTTPS_PROXY=... playwright install
  • custom CA via NODE_EXTRA_CA_CERTS
  • slower networks via PLAYWRIGHT_DOWNLOAD_CONNECTION_TIMEOUT
  • internal mirror via PLAYWRIGHT_DOWNLOAD_HOST (Playwright)

Fix

export HTTPS_PROXY="https://your-proxy"
python -m playwright install chromium

If your org MITMs TLS with a private CA, you often need NODE_EXTRA_CA_CERTS too. (Playwright)


Cause 5: You are on Gradio or Hugging Face Spaces and only used requirements.txt

This is a frequent “it installs the library but never runs the browser download step” trap.

The HF forum has the exact question: they installed Playwright via requirements but couldn’t figure out how to run playwright install, and the app errors without it. (Hugging Face Forums)

Solutions

  1. Use Docker Spaces and put the install step in your Dockerfile (best reliability). HF docs explain Docker Spaces and note runtime user and persistence constraints. (Hugging Face)
  2. If you cannot use Docker, run python -m playwright install at startup (works but slow and requires outbound network every cold start).

Also note: HF Docker Spaces run with user ID 1000 by default, and disk data is lost on restart unless you enable persistent storage. That matters because browsers in ~/.cache/ms-playwright can disappear on restart. (Hugging Face)


Cause 6: You installed “headless shell only” but you are launching headed Chromium

Your code uses headless=False. Headed Chromium needs the full Chromium build, not only the “chromium headless shell” install.

Playwright documents that it ships a regular Chromium build for headed use and a separate headless shell, and that --only-shell skips the full build. (Playwright)

If you previously ran:

playwright install --only-shell

…then headless=False can lead to missing “full Chromium” artifacts.

Fix

python -m playwright install chromium
# without --only-shell

What to do next: a clear decision tree

If you control the machine (local dev, VM)

Run this once in the same venv:

pip install -U playwright
python -m playwright install --with-deps chromium

This is the documented one-shot “browsers + OS deps” pattern. (Playwright)

If this is Docker / CI

Do browser install in the image build:

pip install playwright
python -m playwright install --with-deps chromium

The CI doc shows the same concept (playwright install --with-deps). (Playwright)

If this is Gradio on Hugging Face Spaces

Prefer Docker Spaces and bake it into the Dockerfile. HF explicitly supports Docker Spaces for setups beyond standard Gradio, and notes user and persistence behavior that affects caches. (Hugging Face)


Debugging commands that usually pinpoint the issue in 60 seconds

  1. Confirm where Playwright expects browsers and what is installed:
python -m playwright install --list

Playwright documents install --list and the ms-playwright cache model. (Playwright)

  1. Check whether the expected folder exists:
ls -la /root/.cache/ms-playwright
  1. If the folder exists but the number differs (example: you have chromium-1190 but it wants chromium-1200)
    That is usually a version mismatch between the Playwright package used to install browsers and the Playwright package used at runtime. Re-run install from the runtime env using python -m playwright ....

About “install Selenium in Gradio”

That Selenium guide is solving a different problem: Selenium uses a system browser + driver model.

Your error is Playwright-specific: it cannot find its own downloaded Chromium in ms-playwright. Fixing Playwright is usually simpler than switching stacks.

If you truly want to use system Chrome with Playwright instead, Playwright supports “branded” Chrome/Edge channels, but that is a separate configuration path. (Playwright)


High-quality reading list (with what each is good for)


Summary

  • The error means “Playwright cannot find the pinned Chromium binary in ms-playwright cache.” (Playwright)
  • Fix is usually python -m playwright install chromium in the same runtime env and user. (Playwright)
  • On Linux, often add --with-deps (or install-deps). (Playwright)
  • In Gradio/HF deployments, you often need Docker or a startup install step because requirements.txt alone does not run playwright install. (Hugging Face Forums)

Thanks a lot toJohn for your reply in details. I would try the fix of cause 6 first (I am not sure why the instructor use headless=False, possibly for demo reason. People are normally using headless=True at default). If it is still not working. I will try the fix of cause 5 the next. I figured out the only way to install the binary is to use docker container. I have never tried docker deployment to Huggingface. That requires to install Docker SDK to my HF space. I should be able to find the instruction if I get to that point.

Again, thanks for all your help.

1 Like

playwright._impl._errors.Error: BrowserType.launch: Executable doesn’t exist at /root/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell

Haha, headless also requires chromium_headless installation.

1 Like
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
RUN pip install playwright
# RUN python -m playwright install --with-deps chromium
RUN python -m playwright install --only-shell

File “/usr/local/lib/python3.12/site-packages/playwright/_impl/_connection.py”, line 559, in wrap_api_call
raise rewrite_error(error, f"{parsed_st[‘apiName’]}: {error}") from None
playwright._impl._errors.Error: BrowserType.launch: Executable doesn’t exist at /home/user/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell

still got the above and also some Gradio error that I did not have it before. This might require both Gradio and Docker SDK installed. I got another space working without Playwright for now. I will revisit it when I have time. Thanks.

1 Like

Oh. Be aware that user permission settings in Docker Spaces can be tricky.


The reliable way to run Playwright behind a Gradio UI on Hugging Face Spaces is a Docker Space with a Dockerfile that (1) makes Gradio reachable on port 7860 and (2) makes Playwright’s browser binaries exist for the runtime user.

Playwright errors like “Executable doesn’t exist at …/ms-playwright/…” happen when the Playwright Python package is present but the matching browser binary folder is missing at runtime. Playwright stores those binaries under a cache directory such as ~/.cache/ms-playwright on Linux, so “which user and which HOME” you run as matters.


Background you need to internalize

1) Playwright is two installs

  • Install the Python library (pip install playwright)
  • Install browser binaries (python -m playwright install …), which downloads into the Playwright cache path (Linux defaults under ~/.cache/ms-playwright).

2) Headless still needs a browser binary

Headless mode still runs a real Chromium build. Playwright even has a special “headless shell” package, and --only-shell installs only chromium-headless-shell instead of the full Chromium.

3) Docker Spaces run as UID 1000

Hugging Face Docker Spaces run containers as user id 1000 and recommend creating that user to avoid permission and cache issues.

4) Spaces disk is not persistent by default

If you download browsers at runtime into a cache directory, they can disappear on restart unless you enable persistent storage. Docker Spaces persist /data only if you upgrade storage.


Recommended architecture

Use a Docker Space

Hugging Face explicitly supports Docker Spaces by setting sdk: docker in the README YAML and using port 7860 (or app_port).

Use one of these Playwright install strategies

Strategy A (easiest): base on the official Playwright Python image

  • The image includes browsers and system dependencies, but not the Python Playwright package, so you still pip install playwright.
  • Pin versions. Playwright recommends pinning Docker image tags rather than relying on “latest.”

Strategy B (more control): install browsers during your Docker build

  • Run python -m playwright install --with-deps for Linux dependencies.
  • Use PLAYWRIGHT_BROWSERS_PATH so browsers go into a directory that the runtime user can read.

Working template (minimal, correct defaults)

1) README.md YAML (Docker Space switch)

At the top of README.md:

---
sdk: docker
app_port: 7860
---

This is the documented way to configure a Docker Space and port.

2) requirements.txt

Keep it boring and pinned if you can:

gradio
playwright

3) Dockerfile (Strategy B, installs headless shell only)

This avoids the root vs user HOME cache mismatch by putting browsers in a fixed location.

FROM python:3.12-slim

# Put Playwright browsers in a deterministic path, not ~/.cache.
ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright

WORKDIR /app
COPY requirements.txt /app/requirements.txt
RUN pip install --no-cache-dir -r /app/requirements.txt

# Install browser + Linux deps. Use --only-shell if you only need headless.
RUN python -m playwright install --with-deps --only-shell chromium

# Hugging Face Docker Spaces run as uid 1000. Create and switch to that user.
RUN useradd -m -u 1000 user
RUN chown -R 1000:1000 /app /ms-playwright
USER user

COPY --chown=user:user . /app

# Gradio needs to be reachable from outside the container.
ENV GRADIO_SERVER_NAME=0.0.0.0
ENV GRADIO_SERVER_PORT=7860

EXPOSE 7860
CMD ["python", "app.py"]

Key points in that Dockerfile are directly supported by docs:

  • --with-deps and --only-shell are Playwright install options.
  • Docker Spaces run as UID 1000 and you should handle permissions accordingly.
  • Gradio in Docker should bind to 0.0.0.0 and use port 7860.

4) app.py (Gradio UI calling Playwright)

A simple pattern is “one browser per request.” It is slower but robust.

import gradio as gr
from playwright.async_api import async_playwright

async def fetch_title(url: str) -> str:
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        page = await browser.new_page()
        await page.goto(url, wait_until="domcontentloaded")
        title = await page.title()
        await browser.close()
    return title

with gr.Blocks() as demo:
    url = gr.Textbox(label="URL", value="https://example.com")
    out = gr.Textbox(label="Page title")
    btn = gr.Button("Fetch title")

    btn.click(fetch_title, inputs=url, outputs=out)

    # Playwright is a shared external resource. Keep concurrency low.
    demo.queue(default_concurrency_limit=1)

demo.launch()

Why this shape works well:

  • Gradio recommends using async for I/O-heavy work. Browser automation is I/O-heavy.
  • Gradio’s queue lets you control concurrency; default per-event concurrency is 1 unless configured, which is often what you want for Playwright.
  • Running Playwright inside a request handler avoids keeping a long-lived browser around with unclear lifecycle.

If you want better performance later, reuse a single browser instance and create a new BrowserContext per request. Playwright documents contexts as the isolation primitive.
If you do this, keep concurrency limited and add an async lock.


Persistence and /data on Spaces

If you upgrade to persistent storage, /data persists across restarts in Docker Spaces.

Two practical notes:

  • Browsers downloaded into /data/ms-playwright will survive restarts.
  • /data may not be available at Docker build time in all cases, so don’t rely on installing into /data during docker build. Some users confirm that limitation and instead configure caching at runtime.

Debug checklist for “Executable doesn’t exist …”

When it fails, do these first:

  1. List what Playwright thinks is installed and where:
python -m playwright install --list

Playwright added this specifically to show installed browsers and locations.

  1. Confirm the runtime user and HOME match your expectations (UID 1000 is typical on Docker Spaces).

  2. If you used --only-shell, confirm you are not trying to launch headed Chromium (headless=False), because --only-shell installs just the headless shell.


Good primary references


Summary

  • Use a Docker Space. Set sdk: docker and app_port: 7860.
  • Install Playwright browsers at build time, and avoid HOME-dependent cache paths by setting PLAYWRIGHT_BROWSERS_PATH.
  • Respect HF’s UID 1000 runtime and permissions.
  • Bind Gradio to 0.0.0.0:7860.
  • Use Gradio queue and low concurrency for Playwright tasks.
1 Like

This topic was automatically closed 12 hours after the last reply. New replies are no longer allowed.