d2lang/d2 · error
failed to install Playwright: %w
Error message
failed to install Playwright: %w
What it means
InitPlaywright wraps any error from playwright.Install() (which downloads the Chromium browser binary) with this message. The library calls it to ensure Chromium v149 is available before rendering non-SVG images. It indicates the browser download/install step failed, and the underlying cause is preserved via %w.
Source
Thrown at lib/png/png.go:87
}
page, err := context.NewPage()
if err != nil {
return Playwright{}, fmt.Errorf("failed to start new Playwright page: %w", err)
}
return Playwright{
PW: pw,
Browser: browser,
Page: page,
}, nil
}
func InitPlaywright() (Playwright, error) {
err := playwright.Install(&playwright.RunOptions{
Verbose: false,
Browsers: []string{"chromium"},
})
if err != nil {
return Playwright{}, fmt.Errorf("failed to install Playwright: %w", err)
}
pw, err := playwright.Run()
if err != nil {
return Playwright{}, fmt.Errorf("failed to run Playwright: %w", err)
}
return startPlaywright(pw)
}
func InitPlaywrightWithPrompt() (Playwright, error) {
if os.Getenv("CI") != "" {
return InitPlaywright()
}
// Just try running first. This only works if drivers and browsers are already installed
pw, err := playwright.Run()
if err == nil {
return startPlaywright(pw)View on GitHub (pinned to 0d69dca6f5)
Solutions
- Check network connectivity/proxy settings and retry; set HTTPS_PROXY if behind a corporate proxy
- Ensure the playwright browser cache directory is writable (check $HOME or PLAYWRIGHT_BROWSERS_PATH)
- Free disk space; Chromium download needs several hundred MB
- Pre-install the browser manually (playwright install chromium) and re-run
- Inspect the wrapped cause (%w) for the precise driver error
Example fix
// before
pw, err := InitPlaywright()
if err != nil { log.Fatal(err) }
// after
if err := os.Setenv("PLAYWRIGHT_BROWSERS_PATH", "/tmp/pw-browsers"); err != nil { log.Fatal(err) }
pw, err := InitPlaywright()
if err != nil { log.Fatalf("playwright init: %v (check network/disk)", err) } Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := os.Stat(browserCacheDir()); err != nil && !hasNetwork() { t.Skip("no network for playwright install") } Type guard
var pwe *playwright.Error // inspect wrapped cause
func installCause(err error) error { return errors.Unwrap(err) } Try / catch
pw, err := InitPlaywright()
if err != nil {
var dlErr error
if errors.Is(err, context.DeadlineExceeded) { /* retry with proxy */ }
_ = dlErr
log.Printf("playwright install failed: %v", err)
return fallbackSVGRendering()
} Prevention
- Pre-install browsers in CI images so install is a no-op
- Set PLAYWRIGHT_BROWSERS_PATH to a writable dir
- Verify disk space (>1GB) before rendering
- Set HTTPS_PROXY/NO_PROXY for corporate networks
When it happens
Trigger: Calling InitPlaywright() or InitPlaywrightWithPrompt() when playwright.Install(&playwright.RunOptions{Browsers:["chromium"]}) fails: no network access, download interrupted, insufficient disk space, or unwritable playwright cache directory (e.g. ~/.cache/ms-playwright).
Common situations: CI containers with no internet egress or restricted DNS; corporate proxies blocking the CDN; read-only HOME in sandboxes/Docker; disk full; TLS interception breaking the download.
Related errors
- failed to launch Chromium: %w
- failed to start new Playwright browser context: %w
- failed to start new Playwright page: %w
- failed to run Playwright: %w
- expected status 200 but got %d %s
AI-assisted analysis of d2lang/d2@0d69dca6f5 (2026-08-31).
Data as JSON: /api/errors/952fcb7b32efeba4.
Report an issue: GitHub.