{"record":{"id":"25f157dcc9bdc56a","repo":"Billionmail/BillionMail","slug":"playwright-capture-failed-w-output-s","errorCode":null,"errorMessage":"playwright capture failed: %w\noutput: %s","messagePattern":"playwright capture failed: %w\noutput: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/video_gen/screenshots.go","lineNumber":75,"sourceCode":"\t}\n\n\tresult := &ScreenshotResult{\n\t\tHomepage: filepath.Join(cfg.OutputDir, \"homepage.png\"),\n\t\tContact:  filepath.Join(cfg.OutputDir, \"contact.png\"),\n\t\tGoogle:   filepath.Join(cfg.OutputDir, \"google.png\"),\n\t}\n\n\t// Build the Playwright script that captures all 3 screenshots\n\tscript := buildPlaywrightScript(cfg, result)\n\n\ttimeoutCtx, cancel := context.WithTimeout(ctx, cfg.Timeout)\n\tdefer cancel()\n\n\tcmd := exec.CommandContext(timeoutCtx, \"node\", \"-e\", script)\n\tcmd.Env = append(os.Environ(), \"PLAYWRIGHT_BROWSERS_PATH=0\")\n\tout, err := cmd.CombinedOutput()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"playwright capture failed: %w\\noutput: %s\", err, string(out))\n\t}\n\n\treturn result, nil\n}\n\n// buildPlaywrightScript generates a Node.js script that uses Playwright to\n// capture the 3 screenshots. Exported for testing command construction.\nfunc buildPlaywrightScript(cfg ScreenshotConfig, result *ScreenshotResult) string {\n\tcontactURL := findContactURL(cfg.WebsiteURL)\n\tgoogleURL := buildGoogleMapsURL(cfg.BusinessName)\n\n\treturn fmt.Sprintf(`\nconst { chromium } = require('playwright');\n(async () => {\n  const browser = await chromium.launch({ headless: true });\n  const ctx = await browser.newContext({\n    viewport: { width: %d, height: %d },\n    userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36'","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/video_gen/screenshots.go#L57-L93","documentation":"CaptureScreenshots runs a generated Node.js Playwright script via `node -e` and captures combined stdout/stderr. If the process exits non-zero, the Go error is wrapped with 'playwright capture failed: %w' plus the script's output so the Playwright-side failure is visible.","triggerScenarios":"The embedded Playwright script fails: page.goto timeout, navigation error, browser not installed, target site blocks automation or returns 4xx/5xx, or ctx deadline cancels the command.","commonSituations":"Playwright browsers not installed (missing `npx playwright install`); PLAYWRIGHT_BROWSERS_PATH misconfigured; prospect's website down or blocking headless browsers; 60s timeout too short for slow sites.","solutions":["Read the 'output:' portion of the error — it contains the actual Playwright/Node stack trace","Run `npx playwright install chromium` in the deployment image if browsers are missing","Re-run with a longer timeout or retry for slow/unresponsive target sites","Test the target URLs manually; blocklisted/bot-protected sites need a different capture approach"],"exampleFix":"// before\nout, err := cmd.CombinedOutput()\nif err != nil {\n\treturn nil, fmt.Errorf(\"playwright capture failed: %w\\noutput: %s\", err, string(out))\n}\n// after\nout, err := cmd.CombinedOutput()\nif err != nil {\n\tif errors.Is(ctx.Err(), context.DeadlineExceeded) {\n\t\treturn nil, fmt.Errorf(\"playwright capture timed out after %v\\noutput: %s\", timeout, string(out))\n\t}\n\treturn nil, fmt.Errorf(\"playwright capture failed: %w\\noutput: %s\", err, string(out))\n}","handlingStrategy":"try-catch","validationCode":"if _, err := exec.LookPath(\"node\"); err != nil {\n\treturn fmt.Errorf(\"node not installed\")\n}\nfor _, u := range []string{homepageURL, contactURL, googleURL} {\n\tif _, err := url.ParseRequestURI(u); err != nil {\n\t\treturn fmt.Errorf(\"invalid capture URL %q\", u)\n\t}\n}","typeGuard":null,"tryCatchPattern":"res, err := CaptureScreenshots(ctx, cfg)\nif err != nil && strings.Contains(err.Error(), \"playwright capture failed\") {\n\tlog.Printf(\"playwright output: %s\", extractOutput(err)) // inspect Node-side trace before retrying\n\tif isTransient(err) { return retryCapture(ctx, cfg) }\n}","preventionTips":["Bake `npx playwright install chromium` into the deployment image","Keep PLAYWRIGHT_BROWSERS_PATH consistent between install and runtime","Set a per-page navigation timeout shorter than the process ctx timeout","Pre-check prospect URLs for reachability and bot-protection before capture"],"tags":["playwright","nodejs","screenshot","external-process","browser-automation"],"backgroundTag":"browser-automation-crash","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}