{"record":{"id":"b56c873871b5fdf0","repo":"d2lang/d2","slug":"chromium-installation-cancelled-by-user","errorCode":null,"errorMessage":"chromium installation cancelled by user","messagePattern":"chromium installation cancelled by user","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"lib/png/png.go","lineNumber":116,"sourceCode":"\tif os.Getenv(\"CI\") != \"\" {\n\t\treturn InitPlaywright()\n\t}\n\n\t// Just try running first. This only works if drivers and browsers are already installed\n\tpw, err := playwright.Run()\n\tif err == nil {\n\t\treturn startPlaywright(pw)\n\t}\n\n\tfmt.Print(\"D2 needs to install Chromium v149.0.7827.55 to render non-SVG images. Continue? (y/N): \")\n\treader := bufio.NewReader(os.Stdin)\n\tresponse, err := reader.ReadString('\\n')\n\tif err != nil {\n\t\treturn Playwright{}, fmt.Errorf(\"failed to read user input: %w\", err)\n\t}\n\tresponse = strings.TrimSpace(strings.ToLower(response))\n\tif response != \"y\" && response != \"yes\" {\n\t\treturn Playwright{}, fmt.Errorf(\"chromium installation cancelled by user\")\n\t}\n\n\treturn InitPlaywright()\n}\n\ntype timeoutSetter interface {\n\tSetDefaultTimeout(float64)\n\tSetDefaultNavigationTimeout(float64)\n}\n\nfunc configureTimeout(target timeoutSetter) {\n\tseconds, ok := env.Timeout()\n\tif !ok {\n\t\treturn\n\t}\n\tif seconds < 0 {\n\t\tseconds = 0\n\t}","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/d2lang/d2/blob/0d69dca6f532ceaeacd615d35d1eaa41a238ffdb/lib/png/png.go#L98-L134","documentation":"When the user answers anything other than y/yes to the Chromium install confirmation, InitPlaywrightWithPrompt deliberately returns this error. It is a controlled user-declined outcome, not a malfunction.","triggerScenarios":"User types anything except y or yes (case-insensitive, trimmed) at the 'Continue? (y/N)' prompt during InitPlaywrightWithPrompt().","commonSituations":"User accidentally presses Enter (default is No); scripted input containing unexpected text; user declines a large download on metered connections.","solutions":["Re-run and answer y or yes to proceed with installation","Set CI=1 to skip the prompt entirely if automation should always install","Pre-install Chromium out-of-band and use a path that does not prompt","If declined intentionally, fall back to SVG output instead of PNG rendering"],"exampleFix":"// before\npw, err := InitPlaywrightWithPrompt() // error: cancelled by user\n// after\nif err != nil && strings.Contains(err.Error(), \"cancelled by user\") {\n    log.Println(\"PNG rendering skipped; export SVG instead\")\n    return renderSVG()\n}","handlingStrategy":"try-catch","validationCode":"// no pre-check possible; user decision at runtime\nfmt.Fprintln(os.Stderr, \"Chromium download (~150MB) required\")","typeGuard":"func isUserCancelled(err error) bool { return strings.Contains(err.Error(), \"cancelled by user\") }","tryCatchPattern":"pw, err := InitPlaywrightWithPrompt()\nif err != nil {\n    if isUserCancelled(err) {\n        return renderSVG() // graceful fallback\n    }\n    return err\n}","preventionTips":["Document the y/N prompt in your tool's docs","Offer SVG output as a no-install alternative","Set CI=1 to auto-proceed in automation","Pre-install Chromium to avoid the prompt entirely"],"tags":["go","user-input","cancelled","prompt","consent"],"backgroundTag":"user-cancelled-installation","analyzedSha":"0d69dca6f532ceaeacd615d35d1eaa41a238ffdb","analyzedAt":"2026-08-31T12:19:21.182Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}