Fixing Roo Code's Browser Action Tool That Hangs or Fails to Launch in Remote and Containerized Environments
Asking the agent to open a page and check how it renders works fine on a regular desktop setup, then just hangs indefinitely — no error, no screenshot, no timeout — the moment the same task runs inside a dev container, a remote-SSH session, or a CI-like sandboxed environment. The browser tool isn't broken; it's trying to launch a real Chromium process somewhere that doesn't have what a real browser needs to start.
The Problem
Roo Code's browser automation tool — used to open a URL, take a screenshot, or click through a page as part of a task — works correctly when the editor is running on a regular local desktop. The exact same task, run inside a dev container, over a Remote-SSH connection to a headless server, or inside a CI-style sandboxed environment, simply hangs: no screenshot appears, no error surfaces in the chat, and the task sits waiting indefinitely with nothing visibly happening. Canceling and retrying produces the same silent stall.
Why It Happens
The tool launches a real, local Chromium process, and that process has real operating-system dependencies a minimal environment may not have
Under the hood, the browser tool is backed by a real headless (or headed) Chromium instance, launched as an actual OS process — not a simulated or remote browser. Launching Chromium successfully depends on a set of shared system libraries (for font rendering, GPU/graphics stack components, sandboxing primitives) being present on the host. A minimal container image, a stripped-down CI base image, or a remote server provisioned without a desktop environment in mind frequently lacks one or more of these, and Chromium's own failure mode for a missing dependency is often to stall during launch rather than exit with a clear, loggable error.
Chromium's sandbox needs specific kernel permissions that many containers deliberately restrict
Chromium's default sandboxing uses Linux namespace and seccomp features that require certain kernel capabilities, and many container runtimes restrict exactly those capabilities by default as a security hardening measure, independent of anything Roo Code itself does. A browser launch that depends on the sandbox succeeding can hang or fail specifically because the container's own security posture is blocking a kernel-level operation Chromium expects to be allowed, which has nothing to do with the extension's own configuration.
A remote or containerized environment often has no display server at all, and headless mode isn't automatically assumed everywhere
A desktop machine has a graphical display server available by default; a bare container or a headless remote server frequently doesn't, unless one was deliberately configured. If the browser tool (or the underlying automation library) attempts to launch in a mode that expects a display to be available — rather than an explicitly headless one — the launch can stall waiting on a display connection that will never arrive in that environment.
The Fix
1. Install the specific system libraries Chromium needs, rather than assuming a minimal base image already has them
# On a Debian/Ubuntu-based container or server:
apt-get update && apt-get install -y \
libnss3 libatk-bridge2.0-0 libx11-xcb1 libxcomposite1 \
libxdamage1 libxrandr2 libgbm1 libpango-1.0-0 libasound2
Chromium's launch failure on a minimal image is very often a missing shared library rather than anything specific to Roo Code, and installing the standard set of dependencies headless Chromium needs resolves the stall directly for environments where the container image itself is the limiting factor.
2. Diagnose directly by launching a headless browser manually from the same environment, outside the extension entirely
# If Playwright or Puppeteer's Chromium is already present in node_modules:
node -e "require('playwright').chromium.launch({headless: true}).then(b => { console.log('launched'); b.close(); })"
Launching a headless browser directly from the same shell the extension would run in isolates the problem from Roo Code's own tool logic entirely — if this manual launch also hangs or errors, the cause is confirmed to be the environment itself (missing libraries, sandbox restrictions, no display) rather than anything in how the extension invokes the browser.
3. Explicitly disable the Chromium sandbox when running inside a container whose runtime restricts the required kernel capabilities
# Where the launch configuration can be influenced (project-level browser settings,
# or the environment running the automation), pass the no-sandbox flag:
--no-sandbox --disable-setuid-sandbox
Disabling the sandbox trades a layer of process isolation for the ability to launch at all inside a container whose own security restrictions block the sandbox's required kernel operations — an acceptable trade-off specifically inside an already-isolated container environment, where the container boundary itself provides a separate layer of isolation.
4. Confirm headless mode is explicitly configured rather than relying on an environment-dependent default
Check the relevant browser-automation setting (whichever layer exposes it —
project configuration, environment variables, or the underlying library's
launch options) and confirm it's set to headless rather than left on an
auto-detected default that may assume a display is available.
Making headless mode an explicit setting, rather than trusting an automatic detection that may behave differently across a desktop, a container, and a remote server, removes the specific failure mode where the launch silently waits for a display connection that a headless environment will never provide.
Why This Works
Each fix addresses a different real dependency a launched Chromium process has, all of which a desktop environment satisfies invisibly and a minimal remote or containerized one often doesn't. Installing the missing shared libraries resolves the most common silent-stall cause directly. Testing the browser launch manually, outside the extension, isolates whether the environment itself is the problem before assuming anything about Roo Code's own tool logic. Disabling the sandbox addresses container runtimes that restrict the kernel capabilities Chromium's default sandboxing expects. And explicitly forcing headless mode removes the specific case where the launch silently waits on a display that was never going to appear.
Conclusion
A browser action that hangs indefinitely in a remote or containerized environment isn't a bug in Roo Code's tool itself — it's a real Chromium process failing to launch because that environment is missing something a desktop machine provides invisibly: shared libraries, unrestricted sandbox permissions, or a display server. Install the specific libraries headless Chromium needs, test a browser launch manually outside the extension to isolate the actual cause, disable the sandbox when a container's own security restrictions block it, and explicitly configure headless mode rather than relying on an environment-dependent default.
