router-for-me/CLIProxyAPI · warning

failed to start browser command: %w

Error message

failed to start browser command: %w

What it means

A browser command was selected, but cmd.Start() failed to spawn it. Unlike the lookup failure (error 297), the binary exists on PATH; the exec itself failed — permission denied, broken launcher script, missing dynamic library, or resource limits.

Source

Thrown at internal/browser/browser.go:74

		// Try common Linux browsers in order of preference
		browsers := []string{"xdg-open", "x-www-browser", "www-browser", "firefox", "chromium", "google-chrome"}
		for _, browser := range browsers {
			if _, err := exec.LookPath(browser); err == nil {
				cmd = exec.Command(browser, url)
				break
			}
		}
		if cmd == nil {
			return fmt.Errorf("no suitable browser found on Linux system")
		}
	default:
		return fmt.Errorf("unsupported operating system: %s", runtime.GOOS)
	}

	log.Debugf("Running command: %s %v", cmd.Path, cmd.Args[1:])
	err := cmd.Start()
	if err != nil {
		return fmt.Errorf("failed to start browser command: %w", err)
	}

	log.Debug("Successfully opened URL using platform-specific command")
	return nil
}

// IsAvailable checks if the system has a command available to open a web browser.
// It verifies the presence of necessary commands for the current operating system.
//
// Returns:
//   - true if a browser can be opened, false otherwise.
func IsAvailable() bool {
	// First check if open-golang can work
	testErr := open.Run("about:blank")
	if testErr == nil {
		return true
	}

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Check the wrapped error — exec.ErrNotFound vs permission denied vs library error point to different fixes
  2. For headless use, run with --no-browser and open the printed verification URI manually
  3. Reinstall/repair the launcher package (xdg-utils) or the browser if its binary is broken
  4. Set DISPLAY/WAYLAND_DISPLAY correctly when a GUI session exists

Example fix

# before
$ cli-proxy-api --login
# error: failed to start browser command: exec: ... (no DISPLAY)

# after
$ cli-proxy-api --login --no-browser
# then open the printed URL on any machine with a browser
Defensive patterns

Strategy: fallback

Validate before calling

if !browser.IsAvailable() {
    log.Infof("browser unavailable; open manually: %s", url)
    return nil
}

Try / catch

if err := browser.OpenURL(url); err != nil {
    log.Warnf("browser launch failed (%v); open manually: %s", err, url)
    // non-fatal: OAuth continues via the printed URL
}

Prevention

When it happens

Trigger: xdg-open exists but errors out immediately (broken .desktop handling, no DISPLAY under X11, exec format error), or a found binary lacks execute permission or its shared libraries.

Common situations: Headless session with no DISPLAY/WAYLAND_DISPLAY where GUI browsers fail to start; damaged xdg-utils install; containers with a browser binary but missing libs; PATH shims that shadow a real browser with a non-executable file.

Related errors


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/85aeb246774b7cfa. Report an issue: GitHub.