{"record":{"id":"2b0570e12f549a9e","repo":"alibaba/open-code-review","slug":"no-browser-opener-available","errorCode":null,"errorMessage":"no browser opener available","messagePattern":"no browser opener available","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/viewer/browser.go","lineNumber":221,"sourceCode":"func openBrowser(url string) error {\n\treturn openBrowserCandidates(browserCandidates(runtime.GOOS, os.Getenv(\"BROWSER\"), url))\n}\n\n// openBrowserCandidates tries each candidate in turn. Every failure is reported,\n// not just the first: with $BROWSER set to something uninstalled and no platform\n// opener present either, hearing only about $BROWSER would suggest fixing that\n// variable is enough.\nfunc openBrowserCandidates(candidates [][]string) error {\n\tvar errs []error\n\tfor _, argv := range candidates {\n\t\terr := runBrowserCmd(exec.Command(argv[0], argv[1:]...))\n\t\tif err == nil {\n\t\t\treturn nil\n\t\t}\n\t\terrs = append(errs, fmt.Errorf(\"%s: %w\", argv[0], err))\n\t}\n\tif len(errs) == 0 {\n\t\treturn errors.New(\"no browser opener available\")\n\t}\n\treturn errors.Join(errs...)\n}\n","sourceCodeStart":203,"sourceCodeEnd":225,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/internal/viewer/browser.go#L203-L225","documentation":"openBrowserCandidates tries each configured browser opener command; if the candidate list is empty, it throws 'no browser opener available'. If candidates existed but all failed, it instead joins their per-command errors — this specific error means nothing was ever attempted.","triggerScenarios":"Calling openBrowser (via viewer functionality) on a platform where no known browser opener binary (e.g. xdg-open, open, cmd start variants) was found to build the candidate list.","commonSituations":"Minimal/headless Linux containers or CI with no xdg-open installed; stripped-down Docker images; PATH missing standard system directories; unusual platforms with no recognized opener.","solutions":["Install a browser opener, e.g. apt-get install xdg-utils on Debian/Ubuntu containers.","Ensure the opener binary is on PATH (echo $PATH; which xdg-open).","Open the viewer URL manually and print it instead of relying on browser auto-open in headless environments.","On macOS/Windows verify platform detection is not misclassifying the OS so the right opener is added to candidates."],"exampleFix":"// before\n// headless CI: openBrowser() -> no browser opener available\nfmt.Println(url) // print instead\n// after\n// on the host/container:\nsudo apt-get install -y xdg-utils\nxdg-open http://127.0.0.1:PORT/...","handlingStrategy":"fallback","validationCode":"function hasBrowserOpener() {\n  const candidates = process.platform === 'darwin' ? ['open']\n    : process.platform === 'win32' ? ['cmd']\n    : ['xdg-open'];\n  return candidates.some(c => { try { require('child_process').execSync(`command -v ${c}`, {stdio:'ignore'}); return true; } catch { return false; } });\n}","typeGuard":null,"tryCatchPattern":"url, err := viewer.Open(...)\nif err != nil {\n    if errors.Is(err, errNoBrowser) || strings.Contains(err.Error(), \"no browser opener\") {\n        fmt.Println(\"Open manually:\", url)\n        return nil\n    }\n    return err\n}","preventionTips":["Install xdg-utils in Linux containers/CI images that need browser opening","Keep standard system dirs on PATH so openers are discoverable","In headless environments, print the viewer URL instead of auto-opening","Detect headless (no DISPLAY) up front and skip browser opening"],"tags":["browser","viewer","go","platform"],"backgroundTag":"no-browser-opener-available","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}