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
- Run `playwright install chromium` (or `playwright install`) in the same environment the sandbox uses.
- If system dependencies are missing, also run `playwright install-deps chromium` (Linux).
- For the opensandbox provider, bake `playwright install --with-deps` into the sandbox image or ensure PLAYWRIGHT_BROWSERS_PATH is mounted/valid inside it.
- 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
- Add `playwright install --with-deps chromium` to Dockerfile/CI setup steps.
- Cache ~/.cache/ms-playwright in CI alongside the venv.
- Reinstall browsers after every playwright package version bump.
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
- Timeout ({config.timeout_seconds}s) scraping {[r.url for r i
- Scrape script failed (exit_code={result.exit_code}): {error}
- Generator did not return valid JSON.
- Redis cache dependencies are not installed. Install with `uv
- Path '{canonical_path}' does not match any session mount.
AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15).
Data as JSON: /api/errors/b115765ce3522729.
Report an issue: GitHub.