From 5ac36c9719eb573126d3d8a31e5e22e30ea8019b Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 25 Apr 2026 09:11:30 +0100 Subject: [PATCH] fix(browser): detect more Linux Chromium installs (#48563) Co-authored-by: Catalin Lupuleti <105351510+lupuletic@users.noreply.github.com> --- CHANGELOG.md | 1 + docs/tools/browser.md | 4 +- .../browser/src/browser/chrome.executables.ts | 5 +++ extensions/browser/src/browser/chrome.test.ts | 44 +++++++++++++++++++ 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 973f8225630..2303b25514b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Docs: https://docs.openclaw.ai ### Fixes +- Browser/Linux: detect Chromium-based installs under `/opt/google`, `/opt/brave.com`, `/usr/lib/chromium`, and `/usr/lib/chromium-browser` before asking users to set `browser.executablePath`. (#48563) Thanks @lupuletic. - MCP/CLI: retire bundled MCP runtimes at the end of one-shot `openclaw agent` and `openclaw infer model run` gateway/local executions, so repeated scripted runs do not accumulate stdio MCP child processes. Fixes #71457. - OpenAI/Codex image generation: canonicalize legacy `openai-codex.baseUrl` values such as `https://chatgpt.com/backend-api` to the Codex Responses backend before calling `gpt-image-2`, matching the chat transport. Fixes #71460. - Control UI: make `/usage` use the fresh context snapshot for context percentage, and include cache-write tokens in the Usage overview cache-hit denominator. Fixes #47885. Thanks @imwyvern and @Ante042. diff --git a/docs/tools/browser.md b/docs/tools/browser.md index cdf370e725e..0c3ceb0119b 100644 --- a/docs/tools/browser.md +++ b/docs/tools/browser.md @@ -561,7 +561,9 @@ You can override with `browser.executablePath`. Platforms: - macOS: checks `/Applications` and `~/Applications`. -- Linux: looks for `google-chrome`, `brave`, `microsoft-edge`, `chromium`, etc. +- Linux: checks common Chrome/Brave/Edge/Chromium locations under `/usr/bin`, + `/snap/bin`, `/opt/google`, `/opt/brave.com`, `/usr/lib/chromium`, and + `/usr/lib/chromium-browser`. - Windows: checks common install locations. ## Control API (optional) diff --git a/extensions/browser/src/browser/chrome.executables.ts b/extensions/browser/src/browser/chrome.executables.ts index 8f3e727c177..f5a07395c99 100644 --- a/extensions/browser/src/browser/chrome.executables.ts +++ b/extensions/browser/src/browser/chrome.executables.ts @@ -555,14 +555,18 @@ export function findChromeExecutableLinux(): BrowserExecutable | null { { kind: "chrome", path: "/usr/bin/google-chrome" }, { kind: "chrome", path: "/usr/bin/google-chrome-stable" }, { kind: "chrome", path: "/usr/bin/chrome" }, + { kind: "chrome", path: "/opt/google/chrome/chrome" }, { kind: "brave", path: "/usr/bin/brave-browser" }, { kind: "brave", path: "/usr/bin/brave-browser-stable" }, { kind: "brave", path: "/usr/bin/brave" }, { kind: "brave", path: "/snap/bin/brave" }, + { kind: "brave", path: "/opt/brave.com/brave/brave-browser" }, { kind: "edge", path: "/usr/bin/microsoft-edge" }, { kind: "edge", path: "/usr/bin/microsoft-edge-stable" }, { kind: "chromium", path: "/usr/bin/chromium" }, { kind: "chromium", path: "/usr/bin/chromium-browser" }, + { kind: "chromium", path: "/usr/lib/chromium/chromium" }, + { kind: "chromium", path: "/usr/lib/chromium-browser/chromium-browser" }, { kind: "chromium", path: "/snap/bin/chromium" }, ]; @@ -575,6 +579,7 @@ export function findGoogleChromeExecutableLinux(): BrowserExecutable | null { "/usr/bin/google-chrome-stable", "/usr/bin/google-chrome-beta", "/usr/bin/google-chrome-unstable", + "/opt/google/chrome/chrome", "/snap/bin/google-chrome", ]); } diff --git a/extensions/browser/src/browser/chrome.test.ts b/extensions/browser/src/browser/chrome.test.ts index dde16b2e39e..43aef226cb4 100644 --- a/extensions/browser/src/browser/chrome.test.ts +++ b/extensions/browser/src/browser/chrome.test.ts @@ -15,6 +15,7 @@ import { decorateOpenClawProfile, diagnoseChromeCdp, ensureProfileCleanExit, + findChromeExecutableLinux, findChromeExecutableMac, findChromeExecutableWindows, formatChromeCdpDiagnostic, @@ -295,6 +296,38 @@ describe("browser chrome helpers", () => { exists.mockRestore(); }); + it("finds common Linux Chromium package paths", () => { + for (const target of [ + "/usr/lib/chromium/chromium", + "/usr/lib/chromium-browser/chromium-browser", + ]) { + const exists = mockExistsSync((pathValue) => pathValue === target); + const exe = findChromeExecutableLinux(); + expect(exe).toEqual({ kind: "chromium", path: target }); + exists.mockRestore(); + } + }); + + it("finds common Linux /opt Chrome and Brave paths", () => { + const cases = [ + { kind: "chrome", path: "/opt/google/chrome/chrome" }, + { kind: "brave", path: "/opt/brave.com/brave/brave-browser" }, + ] as const; + + for (const candidate of cases) { + const exists = mockExistsSync((pathValue) => pathValue === candidate.path); + const exe = findChromeExecutableLinux(); + expect(exe).toEqual(candidate); + exists.mockRestore(); + } + }); + + it("returns null when no Chrome candidate exists on Linux", () => { + const exists = vi.spyOn(fs, "existsSync").mockReturnValue(false); + expect(findChromeExecutableLinux()).toBeNull(); + exists.mockRestore(); + }); + it("picks the first existing Chrome candidate on Windows", () => { vi.stubEnv("LOCALAPPDATA", "C:\\Users\\Test\\AppData\\Local"); const exists = mockExistsSync((pathStr) => { @@ -665,6 +698,17 @@ describe("chrome executables", () => { path: "/usr/bin/google-chrome-unstable", }); }); + + it("finds Linux Google Chrome under /opt", () => { + vi.spyOn(fs, "existsSync").mockImplementation((candidate) => { + return String(candidate) === "/opt/google/chrome/chrome"; + }); + + expect(resolveGoogleChromeExecutableForPlatform("linux")).toEqual({ + kind: "chrome", + path: "/opt/google/chrome/chrome", + }); + }); }); describe("browser chrome launch args", () => {