From 97888fed483c1e867666b6beb4eb03e409cc9481 Mon Sep 17 00:00:00 2001 From: xxxigm Date: Mon, 22 Jun 2026 21:45:56 +0700 Subject: [PATCH] fix(install): drop system-browser fallback + auto-repair stale snap override The installer scanned PATH/well-known locations for a Chrome/Chromium binary and, when found, skipped the bundled Playwright Chromium download and wrote that path into ~/.hermes/.env as AGENT_BROWSER_EXECUTABLE_PATH. On Snap-based systems `command -v chromium` resolves to /snap/bin/chromium, whose sandbox blocks agent-browser's control socket under /tmp -- so every browser_navigate hung until the 60s timeout fired ("opening web page failed"). Drop the system-browser fallback entirely (per maintainer direction): find_system_browser()/Find-SystemBrowser now honor ONLY an explicit, user-set AGENT_BROWSER_EXECUTABLE_PATH override -- no PATH scan, no well-known-path scan. A /snap/* path is rejected even when set explicitly, since its confinement is the bug. Applied to both install.sh (Linux/macOS) and install.ps1 (Windows). Crucially, also auto-repair already-affected installs: the bad snap path persists in .env and is read directly by the runtime, and the installer skips re-config when AGENT_BROWSER_EXECUTABLE_PATH is already set ("already configured"), so a plain reinstall/update never recovered an existing user. New strip_snap_browser_override() removes a snap-pointing AGENT_BROWSER_EXECUTABLE_PATH (and its auto-written comment) from .env on every install/update, run from both browser-setup paths (install_node_deps and ensure_browser), so updating is enough to recover. A deliberately-set non-snap override is left untouched. docker/stage2-hook.sh is intentionally untouched: it discovers the bundled Playwright Chromium, not a system browser. --- scripts/install.ps1 | 25 ++++++------- scripts/install.sh | 90 +++++++++++++++++++++++++++++---------------- 2 files changed, 70 insertions(+), 45 deletions(-) diff --git a/scripts/install.ps1 b/scripts/install.ps1 index 3626d5b0f28..b93df59cb0f 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -284,18 +284,17 @@ function Resolve-NpmCmd { } function Find-SystemBrowser { - $candidates = @( - "${env:ProgramFiles}\Google\Chrome\Application\chrome.exe", - "${env:ProgramFiles(x86)}\Google\Chrome\Application\chrome.exe", - "${env:LOCALAPPDATA}\Google\Chrome\Application\chrome.exe", - "${env:ProgramFiles}\Microsoft\Edge\Application\msedge.exe", - "${env:ProgramFiles(x86)}\Microsoft\Edge\Application\msedge.exe", - "${env:ProgramFiles}\Chromium\Application\chrome.exe", - "${env:LOCALAPPDATA}\Chromium\Application\chrome.exe" - ) - foreach ($p in $candidates) { - if (Test-Path $p) { return $p } - } + # Honor ONLY an explicit, user-set AGENT_BROWSER_EXECUTABLE_PATH override. + # + # We no longer scan well-known install locations for a system browser. + # Auto-detection silently bound the install to an arbitrary binary instead + # of the bundled Playwright Chromium, which made the browser tool behave + # differently across hosts (and, on Linux, picked up a sandboxed Snap + # Chromium that hangs every browser_navigate). Every install now uses the + # bundled Chromium unless the user explicitly points elsewhere. + $override = $env:AGENT_BROWSER_EXECUTABLE_PATH + if ([string]::IsNullOrWhiteSpace($override)) { return $null } + if (Test-Path $override) { return $override } return $null } @@ -346,7 +345,7 @@ function Install-AgentBrowser { $sysBrowser = Find-SystemBrowser if ($sysBrowser) { Write-BrowserEnv -BrowserPath $sysBrowser - Write-Info "System browser detected -- skipping Chromium download" + Write-Info "Explicit browser override set -- skipping bundled Chromium download" } else { $abExe = Join-Path $prefixDir "agent-browser.cmd" if (Test-Path $abExe) { diff --git a/scripts/install.sh b/scripts/install.sh index a969f31facd..92bb2679ea3 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -1777,42 +1777,66 @@ SOUL_EOF } find_system_browser() { - # Prefer a user-specified browser path, then common Linux/macOS Chrome and - # Chromium command names. Arch-family distributions commonly ship plain - # `chromium`, while Debian-family systems often use `chromium-browser`. - if [ -n "${AGENT_BROWSER_EXECUTABLE_PATH:-}" ]; then - if [ -x "$AGENT_BROWSER_EXECUTABLE_PATH" ]; then - echo "$AGENT_BROWSER_EXECUTABLE_PATH" - return 0 - fi - if command -v "$AGENT_BROWSER_EXECUTABLE_PATH" >/dev/null 2>&1; then - command -v "$AGENT_BROWSER_EXECUTABLE_PATH" - return 0 - fi + # Honor ONLY an explicit, user-set AGENT_BROWSER_EXECUTABLE_PATH override. + # + # We deliberately do NOT scan PATH or well-known app locations any more. + # Auto-detection silently bound the install to whatever `command -v chromium` + # resolved to — most damagingly a Snap Chromium (/snap/bin/chromium), whose + # sandbox blocks agent-browser's control socket under /tmp, so every + # browser_navigate hung until the 60s timeout fired ("opening web page + # failed"). Every install now uses the bundled Playwright Chromium unless the + # user explicitly points elsewhere. + local override="${AGENT_BROWSER_EXECUTABLE_PATH:-}" + + if [ -z "$override" ]; then + return 1 fi - local candidate - for candidate in google-chrome google-chrome-stable chromium chromium-browser chrome; do - if command -v "$candidate" >/dev/null 2>&1; then - command -v "$candidate" - return 0 - fi - done + # A Snap binary is never a valid target — its confinement is the very bug we + # are fixing — so reject it even when set explicitly. + case "$override" in + /snap/*) return 1 ;; + esac - if [ "$(uname)" = "Darwin" ]; then - for app in \ - "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \ - "/Applications/Chromium.app/Contents/MacOS/Chromium"; do - if [ -x "$app" ]; then - echo "$app" - return 0 - fi - done + if [ -x "$override" ]; then + echo "$override" + return 0 + fi + if command -v "$override" >/dev/null 2>&1; then + command -v "$override" + return 0 fi return 1 } +strip_snap_browser_override() { + # Existing installs created before the system-browser fallback was dropped + # may carry an auto-written AGENT_BROWSER_EXECUTABLE_PATH pointing at a Snap + # Chromium (/snap/bin/chromium). That path is the root cause of the "opening + # web page failed" hang, and the runtime reads it straight from .env — so + # removing the fallback in the installer is not enough on its own. Strip any + # snap-pointing override here (and its auto-written comment) so the bundled + # Chromium download runs and the agent stops using the broken binary. A + # deliberately-set non-snap override is left untouched. + local env_file="$HERMES_HOME/.env" + + [ -f "$env_file" ] || return 0 + grep -Eq '^AGENT_BROWSER_EXECUTABLE_PATH=/snap/' "$env_file" 2>/dev/null || return 0 + + local tmp + tmp="$(mktemp)" || return 0 + if grep -Ev '^AGENT_BROWSER_EXECUTABLE_PATH=/snap/|^# Hermes Agent browser tools' "$env_file" > "$tmp"; then + mv "$tmp" "$env_file" + log_warn "Removed stale Snap browser override (AGENT_BROWSER_EXECUTABLE_PATH=/snap/...) from $env_file" + log_info "Hermes will use the bundled Chromium instead." + # Drop it from this process too so the rest of the run doesn't re-detect it. + unset AGENT_BROWSER_EXECUTABLE_PATH + else + rm -f "$tmp" + fi +} + run_browser_install_with_timeout() { local timeout_seconds="$1" shift @@ -1848,7 +1872,7 @@ configure_browser_env_from_system_browser() { { echo "" - echo "# Hermes Agent browser tools — use the system Chrome/Chromium binary." + echo "# Hermes Agent browser tools — explicit browser override." echo "AGENT_BROWSER_EXECUTABLE_PATH=$browser_path" } >> "$env_file" log_success "Configured browser tools to use $browser_path" @@ -1887,10 +1911,11 @@ install_node_deps() { log_info " sudo npx playwright install-deps chromium" else log_info "Installing browser engine (Playwright Chromium)..." + strip_snap_browser_override DETECTED_BROWSER_EXECUTABLE="$(find_system_browser 2>/dev/null || true)" if [ -n "$DETECTED_BROWSER_EXECUTABLE" ]; then - log_success "Found system Chrome/Chromium at $DETECTED_BROWSER_EXECUTABLE" - log_info "Skipping Playwright browser download; Hermes will use the system browser." + log_success "Using explicit browser override: $DETECTED_BROWSER_EXECUTABLE" + log_info "Skipping bundled Chromium download (AGENT_BROWSER_EXECUTABLE_PATH is set)." else case "$DISTRO" in ubuntu|debian|raspbian|pop|linuxmint|elementary|zorin|kali|parrot) @@ -2225,11 +2250,12 @@ ensure_browser() { rm -f "$log_file" export PATH="$HERMES_HOME/node/bin:$PATH" + strip_snap_browser_override local sys_browser sys_browser="$(find_system_browser 2>/dev/null || true)" if [ -n "$sys_browser" ]; then configure_browser_env_from_system_browser "$sys_browser" - log_info "System browser detected -- skipping Chromium download" + log_info "Explicit browser override set -- skipping bundled Chromium download" return 0 fi