srbhr/Resume-Matcher · error · PDFRenderError
PDF rendering failed. Please try again, or try a simpler res
Error message
PDF rendering failed. Please try again, or try a simpler resume or a different template.
What it means
Catch-all PDFRenderError raised by _raise_playwright_error for any PlaywrightError that is neither a missing executable nor connection-refused. The raw Playwright message (which can contain internal navigation URLs and a full call log) is logged server-side; the client gets a generic message to avoid leaking internals and overflowing the error modal.
Source
Thrown at apps/backend/app/pdf.py:252
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(
"PDF rendering failed. Please try again, or try a simpler resume or a "
"different template."
) from error
def _loop_supports_subprocess() -> bool:
if sys.platform != "win32":
return True
try:
loop = asyncio.get_running_loop()
except RuntimeError:
return True
return loop.__class__.__name__ == "ProactorEventLoop"
async def close_pdf_renderer() -> None:
"""Close the Playwright browser instance."""
global _playwright, _browserView on GitHub (pinned to 116f9cc3b0)
Solutions
- Check backend logs for the full server-side error (logger.error records the raw Playwright message)
- Retry the request — transient crashes/timeouts often succeed on a second attempt
- Simplify the resume content or switch to a simpler template to reduce render cost
- Increase Playwright timeouts / page.goto wait settings if renders are consistently slow
- Raise container memory limits or run renders in a queue to reduce concurrent Chromium load
Defensive patterns
Strategy: try-catch
Validate before calling
def is_generic_render_failure(err: Exception) -> bool:
msg = str(err)
return not ("Executable doesn't exist" in msg or "net::ERR_CONNECTION_REFUSED" in msg) Try / catch
try:
pdf = await render_resume_pdf(url, selector)
except PDFRenderError as e:
if "PDF rendering failed" in str(e):
show_user_toast("PDF render failed — try again or simplify the resume")
else:
raise Prevention
- Set generous but bounded Playwright timeouts in the renderer config
- Monitor server logs (the raw Playwright message is logged there) for recurring crash patterns
- Right-size container memory for headless Chromium
- Queue PDF renders to limit concurrent browser instances
- Keep templates light; test large resumes in CI
When it happens
Trigger: render_resume_pdf's Playwright call raises any other PlaywrightError — e.g. navigation timeout, page crash, renderer OOM, target closed, or an extremely large/complex resume exceeding rendering limits.
Common situations: Very large resumes or heavy templates timing out the default navigation timeout; headless Chromium crashing in memory-constrained containers; SSL/other navigation failures; transient driver crashes under concurrent PDF renders.
Related errors
- Playwright browser executable is missing, and no system Chro
- Playwright browser executable is missing or out of date. Com
- Cannot connect to frontend for PDF generation. Attempted URL
- PDF renderer failed to initialize.
- Request timed out. If you are running a local LLM, increase
AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28).
Data as JSON: /api/errors/7d377ec7d0a5a598.
Report an issue: GitHub.