zylon-ai/private-gpt · error · RuntimeError

Playwright browsers are not installed. Run `playwright insta

Error message

Playwright browsers are not installed. Run `playwright install` and try again.

What it means

Raised when the scrape script run inside the sandbox session fails and its stderr/stdout matches _BROWSERS_MISSING_PATTERN — i.e. Playwright could not find an installed browser binary. The sandbox (local or opensandbox provider) runs the script with session.python_executable, so the browsers must be present in that execution environment, not just on the host.

Source

Thrown at private_gpt/components/web/scraper/runner.py:133

    total_timeout = config.timeout_seconds * max(1, len(config.requests))
    result = await session.exec(
        f"{session.python_executable} {shlex.quote(SCRIPT_FILENAME)}"
        f" {shlex.quote(CONFIG_FILENAME)}",
        SandboxExecOptions(
            cwd=base_dir, timeout=total_timeout + _EXEC_TIMEOUT_MARGIN_SECONDS
        ),
    )

    if result.exit_code == 124:
        raise TimeoutError(
            f"Timeout ({config.timeout_seconds}s) scraping "
            f"{[r.url for r in config.requests]}"
        )
    if result.failed:
        error = result.stderr or result.stdout
        if _BROWSERS_MISSING_PATTERN.search(error):
            raise RuntimeError(
                "Playwright browsers are not installed. "
                "Run `playwright install` and try again."
            )
        raise RuntimeError(
            f"Scrape script failed (exit_code={result.exit_code}): {error}"
        )

    results_raw = json.loads(
        (await session.read_file(posixpath.join(base_dir, RESULTS_FILENAME))).decode(
            "utf-8"
        )
    )
    by_output_path = {entry["output_path"]: entry for entry in results_raw}

    outputs: list[str | Exception] = []
    for request in config.requests:
        entry = by_output_path.get(request.output_path)
        if entry is None:

View on GitHub (pinned to 4a030776a3)

Solutions

  1. Run `playwright install chromium` (or `playwright install`) in the same environment the sandbox uses.
  2. If system dependencies are missing, also run `playwright install-deps chromium` (Linux).
  3. For the opensandbox provider, bake `playwright install --with-deps` into the sandbox image or ensure PLAYWRIGHT_BROWSERS_PATH is mounted/valid inside it.
  4. Pin the playwright version and reinstall browsers after every upgrade so binary revision matches the package.

Example fix

# before: browsers absent, scrape raises RuntimeError
# after (Dockerfile / setup)
RUN uv sync --inexact --extra ingest-markup
RUN uv run playwright install --with-deps chromium
Defensive patterns

Strategy: validation

Validate before calling

import shutil
from playwright.sync_api import sync_playwright

def browsers_available() -> bool:
    try:
        with sync_playwright() as p:
            return p.chromium.executable_path is not None
    except Exception:
        return False

assert browsers_available(), 'run: playwright install chromium'

Type guard

def is_browsers_missing_error(exc: BaseException) -> bool:
    return isinstance(exc, RuntimeError) and 'Playwright browsers' in str(exc)

Try / catch

try:
    outputs = await run_scrape_in_session(session, base_dir, config)
except RuntimeError as e:
    if 'Playwright browsers are not installed' in str(e):
        subprocess.run([sys.executable, '-m', 'playwright', 'install', 'chromium'])
        outputs = await run_scrape_in_session(session, base_dir, config)
    raise

Prevention

When it happens

Trigger: First run on a fresh machine/container where `playwright install` was never executed; using the opensandbox provider whose image lacks Chromium; PLAYWRIGHT_BROWSERS_PATH pointing to a location not visible inside the sandbox; upgrading Playwright without reinstalling the matching browser build.

Common situations: Fresh clone + uv sync without the browser step; slim Docker images that pip-install playwright but skip the browser download; CI caches that restore packages but not ~/.cache/ms-playwright; version mismatch after playwright package upgrade.

Related errors


AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15). Data as JSON: /api/errors/b115765ce3522729. Report an issue: GitHub.