srbhr/Resume-Matcher · error · PDFRenderError

Playwright browser executable is missing or out of date. Com

Error message

Playwright browser executable is missing or out of date. Command shown for reference; quote the path if it contains spaces: {command}

What it means

PDFRenderError raised by _raise_playwright_error when Playwright reports "Executable doesn't exist". The installed playwright package cannot find a matching Chromium build, usually because `playwright install` was never run after installing or upgrading the package. The message embeds the exact install command (with sys.executable path) for the operator.

Source

Thrown at apps/backend/app/pdf.py:234


async def _render_resume_pdf_in_thread(
    url: str,
    selector: str,
    pdf_format: str,
    pdf_margins: dict,
) -> bytes:
    return await asyncio.to_thread(
        _render_resume_pdf_sync, url, selector, pdf_format, pdf_margins
    )


def _raise_playwright_error(error: PlaywrightError, url: str) -> NoReturn:
    error_msg = str(error)
    if "Executable doesn't exist" in error_msg:
        exe = sys.executable.replace("\\", "/")
        command = f"{exe} -m playwright install chromium"
        raise PDFRenderError(
            "Playwright browser executable is missing or out of date. "
            "Command shown for reference; quote the path if it contains spaces: "
            f"{command}"
        ) from error
    if "net::ERR_CONNECTION_REFUSED" in error_msg:
        raise PDFRenderError(
            f"Cannot connect to frontend for PDF generation. "
            f"Attempted URL: {url}. "
            f"Please ensure: 1) The frontend is running, "
            f"2) The FRONTEND_BASE_URL environment variable in the backend .env file "
            f"matches the URL where your frontend is accessible."
        ) from error
    # Catch-all: the raw Playwright message can carry internal navigation URLs
    # and a full call log. Log it server-side; return a generic message to the
    # client (CLAUDE.md rule 5 — and it stops the verbose trace from overflowing
    # the client error modal, #811).
    logger.error("PDF rendering failed for %s: %s", url, error_msg)
    raise PDFRenderError(

View on GitHub (pinned to 116f9cc3b0)

Solutions

  1. Run the printed command: `<python> -m playwright install chromium`
  2. If the path contains spaces, quote it as the message says, or run `<python> -m playwright install` with the interpreter from sys.executable
  3. In CI/Docker, add a cached Playwright browser install step pinned to the playwright version in requirements
  4. Verify you are using the same virtualenv/interpreter that installed the browsers
  5. Pin playwright version so upgrades don't silently require a new browser revision

Example fix

// before
pip install playwright
uvicorn app.main:app  # PDF generation fails: executable missing
// after
pip install playwright
python -m playwright install chromium
uvicorn app.main:app
Defensive patterns

Strategy: try-catch

Validate before calling

import shutil, subprocess, sys
from playwright._impl._driver import compute_driver_executable
def chromium_ready() -> bool:
    try:
        out = subprocess.run([sys.executable, "-m", "playwright", "install", "--dry-run", "chromium"], capture_output=True)
        return out.returncode == 0
    except Exception:
        return False

Type guard

def is_missing_executable(err: Exception) -> bool:
    return isinstance(err, Exception) and "Executable doesn't exist" in str(err)

Try / catch

try:
    pdf = await render_resume_pdf(url, selector)
except PDFRenderError as e:
    if "playwright install" in str(e):
        subprocess.run([sys.executable, "-m", "playwright", "install", "chromium"], check=True)
        pdf = await render_resume_pdf(url, selector)
    else:
        raise

Prevention

When it happens

Trigger: render_resume_pdf calls Playwright to launch chromium and the driver raises PlaywrightError containing "Executable doesn't exist" — i.e. no browser binary downloaded for the current playwright version (fresh install, version upgrade, CI cache miss, different Python venv).

Common situations: Fresh clone without running the browser install step; pip/uv upgraded playwright to a version expecting a new Chromium revision; CI pipeline restored a virtualenv but not ~/.cache/ms-playwright; running under a different interpreter (sys.executable) than the one where browsers were installed; Docker image built without the install layer.

Related errors


AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28). Data as JSON: /api/errors/ef20e32ea9a108b4. Report an issue: GitHub.