alibaba/open-code-review · error
no browser opener available
Error message
no browser opener available
What it means
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.
Source
Thrown at internal/viewer/browser.go:221
func openBrowser(url string) error {
return openBrowserCandidates(browserCandidates(runtime.GOOS, os.Getenv("BROWSER"), url))
}
// openBrowserCandidates tries each candidate in turn. Every failure is reported,
// not just the first: with $BROWSER set to something uninstalled and no platform
// opener present either, hearing only about $BROWSER would suggest fixing that
// variable is enough.
func openBrowserCandidates(candidates [][]string) error {
var errs []error
for _, argv := range candidates {
err := runBrowserCmd(exec.Command(argv[0], argv[1:]...))
if err == nil {
return nil
}
errs = append(errs, fmt.Errorf("%s: %w", argv[0], err))
}
if len(errs) == 0 {
return errors.New("no browser opener available")
}
return errors.Join(errs...)
}
View on GitHub (pinned to 5cf97d0d15)
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.
Example fix
// before // headless CI: openBrowser() -> no browser opener available fmt.Println(url) // print instead // after // on the host/container: sudo apt-get install -y xdg-utils xdg-open http://127.0.0.1:PORT/...
Defensive patterns
Strategy: fallback
Validate before calling
function hasBrowserOpener() {
const candidates = process.platform === 'darwin' ? ['open']
: process.platform === 'win32' ? ['cmd']
: ['xdg-open'];
return candidates.some(c => { try { require('child_process').execSync(`command -v ${c}`, {stdio:'ignore'}); return true; } catch { return false; } });
} Try / catch
url, err := viewer.Open(...)
if err != nil {
if errors.Is(err, errNoBrowser) || strings.Contains(err.Error(), "no browser opener") {
fmt.Println("Open manually:", url)
return nil
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- [ocr] WARNING: skipping %s (%d bytes exceeds %d-byte scan li
- "%q %s" (+ positional signature, valid values, usage line, e
- [ocr] Subtask error for group %q: %v
- read background file %q: %w
- background file %q is a directory, not a file
AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02).
Data as JSON: /api/errors/2b0570e12f549a9e.
Report an issue: GitHub.