P2 is_container() False-Positives on Docker Hosts Break Browser Auto-Launch — "Chrome Not Found" on Any Host with Containerd (#58135)
Executive Summary
Hermes Agent's is_container() check uses a mountinfo fallback that scans for containerd substrings. On any plain Linux host running Docker containers with the containerd image store, every running container contributes overlay mount lines containing /var/lib/containerd/... to the host's mount table. The check matches those lines and incorrectly concludes the host itself is a container. The result is cached for the process lifetime, meaning whether your browser works depends on whether a container happened to be running when the gateway started.
The Failure Cascade
| Step | What Happens | Why It's Wrong |
|---|---|---|
| 1 | is_container() returns True | False positive — the host is not a container, but containerd mount lines from running containers triggered the match. |
| 2 | get_subprocess_home() with home_mode: auto returns an empty per-profile directory | Hermes assumes it is inside a container and provisions a fresh home directory instead of using the real user home. |
| 3 | Every subprocess (browser worker, ACP/CLI executors, dep-ensure) gets HOME={profile}/home | The browser worker cannot find Chrome because the real home path is gone from the environment. |
| 4 | Browser tool fails with "Chrome not found" on every browser_navigate | npx runs with the wrong HOME and cannot locate the installed browser binary. |
The Timing Dependency
The reporter documented a striking case: two identically configured profiles created one minute apart ended up with permanently opposite browser behavior based entirely on gateway start order.
- Gateway A started with no containers running →
is_container()cached asFalse→ browser works. - Gateway B started while A's Docker sandbox was active →
is_container()cached asTrue→ browser broken forever.
Profile B's home/.npm was created at the exact timestamp of its first failing browser_navigate. Profile A's home/ directory stayed completely untouched. This is deterministic misbehavior with a timing trigger.
Root Cause: Mountinfo Fallback Is Too Broad
On cgroup v2 hosts, /proc/1/cgroup is just 0::/, so is_container() falls back to scanning /proc/self/mountinfo for substrings: containerd, kubepods, crio. But every running Docker container adds overlay mount lines to the host's mount table with lowerdir=/var/lib/containerd/... — and the substring match does not distinguish between the host's own root mount and container-generated overlay entries.
The suggested fix: only inspect the root mount (the mountinfo line whose mount point is /), not every overlay mount contributed by running containers. Or do not cache a True obtained solely from the mountinfo fallback.
Impact Assessment
| Dimension | Severity | Detail |
|---|---|---|
| Browser Availability | HIGH | The browser is a core tool. Any host running Docker Desktop or any containerd-backed container can silently lose browser access. |
| Failure Mode | HIGH | Silent and timing-dependent — two identical profiles behave differently based on gateway start order. Extremely hard to debug without the forensic timeline the reporter provided. |
| Scope | HIGH | Affects any Linux host where Docker containers are running. Docker Desktop's default containerd image store makes this the common case. |
| Fix Availability | MEDIUM | Two PRs already open (#58141 and #58145). Workaround exists: set terminal.home_mode: real or TERMINAL_HOME_MODE=real. |
Docker/Container-Detection Bug History
| Issue | Severity | Description |
|---|---|---|
| #50205 | P2 | Docker image missing lark-oapi — Feishu channel silently fails |
| #54354 | P2 | Docker backend first tool call runs on host before image pulled |
| #58135 | P2 | is_container() false-positives, breaks browser on any host with containerd |
⚠️ Pattern: Three distinct Docker bugs now documented. #58135 is the subtlest — it is not a Docker-in-Docker bug, but a host-detection bug triggered by Docker's presence on the host. The containerd substring match in mountinfo is a single-line root cause with cascading consequences across browser, subprocess, and tool availability.
Source Evidence
- GitHub Issue: #58135 — is_container() false-positives on hosts running Docker
- Opened: July 4, 2026
- Reporter: @baleian
- Labels: P2, area/docker, bug, comp/agent, tool/browser, type/bug
- Hermes: v0.17.0 | OS: Ubuntu 24.04.4 LTS on WSL2 + Docker Desktop
- Debug report: paste.rs/os6aV
- PRs: #58141 and #58145 already open
- Reporter willing to submit PR: Yes
📌 https://hermes-agent.reviews/hermes-is-container-false-positive-browser-58135.html
Tracked by hermes-agent.reviews — July 4, 2026