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.
This commit is contained in:
xxxigm 2026-06-22 21:45:56 +07:00 committed by Teknium
parent 0089bd820f
commit 97888fed48
2 changed files with 70 additions and 45 deletions

View file

@ -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) {

View file

@ -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