# NousResearch/hermes-agent · ARM64 and non-sudo installer fixes

## Open now

- 0 issues, 1 PR open on GitHub.
- PR #16343: fix(installer): add arm64 fallback for Playwright setup

These issues and PRs address failures in the installation script, specifically around ARM64 architecture support for Playwright and non-sudo service-user installs on apt-based distributions. No resolution status is assumed.

## TL;DR

- 4 member(s): 0 open issue(s), 1 closed issue(s), 1 open PR(s), 1 merged PR(s), 1 PR(s) closed without merging.
- A fix was merged to main in PR #25814. Verify it addresses your case.
- **Recommended:** read PR #25814 (and any competing PRs below) before filing. Confirm the merged change covers your symptom.

## Maintainer resolution verdict

- Internal-tracker verdict over this cluster's issue members: `unresolved`. This is distinct from the fix status above. Weigh it yourself.

## How this cluster was grouped

- Link evidence (`STRUCTURAL_SPANNING`): every member is connected by structural evidence: shared changed files, or a closing/superseded reference.
- Pairwise link density `0.50`: the share of member pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. `1.00` means every pair is linked.

## Closed / duplicate issues

- #16314: \[Bug\]: The browser installation script used on the arm64 architecture server keeps failing to install; could you please adjust it to make the one-click installation script more user-friendly?

## Prior & competing PRs

- **#25814: fix(install): support non-sudo service-user installs on apt distros**. merged to main · fix tier `verified`
  - maintainer direction: category `merged`
  - files: `scripts/install.sh`, `tests/test_install_sh_browser_install.py`, `website/docs/getting-started/installation.md`
  - fix hunks:
  - `scripts/install.sh`

    ```diff
    @@ -69,6 +69,7 @@ DETECTED_BROWSER_EXECUTABLE=""
     # Options
     USE_VENV=true
     RUN_SETUP=true
    +SKIP_BROWSER=false
     BRANCH="main"
     
     # Detect non-interactive mode (e.g. curl | bash)
    ```

    ```diff
    @@ -91,6 +92,10 @@ while [[ $# -gt 0 ]]; do
                 RUN_SETUP=false
                 shift
                 ;;
    +        --skip-browser|--no-playwright)
    +            SKIP_BROWSER=true
    +            shift
    +            ;;
             --branch)
                 BRANCH="$2"
                 shift 2
    ```

    ```diff
    @@ -112,6 +117,7 @@ while [[ $# -gt 0 ]]; do
                 echo "Options:"
                 echo "  --no-venv      Don't create virtual environment"
                 echo "  --skip-setup   Skip interactive setup wizard"
    +            echo "  --skip-browser Skip Playwright/Chromium install (browser tools won't work)"
                 echo "  --branch NAME  Git branch to install (default: main)"
                 echo "  --dir PATH     Installation directory"
                 echo "                   default (non-root):  ~/.hermes/hermes-agent"
    ```

    ```diff
    @@ -1566,6 +1572,13 @@ install_node_deps() {
             # Playwright's --with-deps only supports apt-based systems natively.
             # For Arch/Manjaro we install the system libs via pacman first.
             # Other systems must install Chromium dependencies manually.
    +        if [ "$SKIP_BROWSER" = true ]; then
    +            log_info "Skipping Playwright/Chromium install (--skip-browser)"
    +            log_info "Browser tools will be unavailable until you run manually:"
    +            log_info "  cd $INSTALL_DIR && npx playwright install chromium"
    +            log_info "On apt-based systems, an admin also needs to run:"
    +            log_info "  sudo npx playwright install-deps chromium"
    +        else
             log_info "Installing browser engine (Playwright Chromium)..."
             DETECTED_BROWSER_EXECUTABLE="$(find_system_browser 2>/dev/null || true)"
             if [ -n "$DETECTED_BROWSER_EXECUTABLE" ]; then
    ```

    ```diff
    @@ -1574,12 +1587,30 @@ install_node_deps() {
             else
                 case "$DISTRO" in
                     ubuntu|debian|raspbian|pop|linuxmint|elementary|zorin|kali|parrot)
    -                    log_info "Playwright may request sudo to install browser system dependencies (shared libraries)."
    -                    log_info "This is standard Playwright setup — Hermes itself does not require root access."
    -                    cd "$INSTALL_DIR" && run_browser_install_with_timeout 600 npx playwright install --with-deps chromium 2>/dev/null || {
    -                        log_warn "Playwright browser installation failed — browser tools will not work."
    -                        log_warn "Try running manually: cd $INSTALL_DIR && npx playwright install --with-deps chromium"
    -                    }
    +                    # Use --with-deps only when sudo is available non-interactively
    +                    # (root, or a user with passwordless sudo). Non-sudo users
    +                    # — typical for systemd service accounts and unprivileged
    +                    # operator users — would otherwise get blocked on an
    +                    # interactive sudo prompt that they can't satisfy. Fall back
    +                    # to the browser-only install in that case, and print the
    +                    # exact command the admin needs to run separately.
    +                    if [ "$(id -u)" -eq 0 ] || (command -v sudo >/dev/null 2>&1 && sudo -n true 2>/dev/null); then
    +                        log_info "Installing Playwright Chromium with system dependencies..."
    +                        cd "$INSTALL_DIR" && run_browser_install_with_timeout 600 npx playwright install --with-deps chromium 2>/dev/null || {
    +                            log_warn "Playwright browser installation failed — browser tools will not work."
    +                            log_warn "Try running manually: cd $INSTALL_DIR && npx playwright install --with-deps chromium"
    +                        }
    +                    else
    +                        log_warn "No sudo available — skipping system-library install (--with-deps)."
    +                        log_info "Ask an administrator to run, one time, as root:"
    +                        log_info "  sudo npx playwright install-deps chromium"
    +                        log_info "  (from $INSTALL_DIR, after Node.js deps are installed)"
    +                        log_info "Installing Chromium binary into this user's Playwright cache..."
    +                        cd "$INSTALL_DIR" && run_browser_install_with_timeout 600 npx playwright install chromium 2>/dev/null || {
    +                            log_warn "Playwright browser installation failed — browser tools will not work."
    +                            log_warn "Try running manually: cd $INSTALL_DIR && npx playwright install chromium"
    +                        }
    +                    fi
                         ;;
                     arch|manjaro|cachyos|endeavouros|garuda)
                         if command -v pacman &> /dev/null; then
    ```

    ```diff
    @@ -1624,6 +1655,7 @@ install_node_deps() {
                         ;;
                 esac
             fi
    +        fi
             log_success "Browser engine setup complete"
         fi
     
    ```
  - `tests/test_install_sh_browser_install.py`

    ```diff
    @@ -32,4 +32,29 @@ def test_playwright_installs_are_timeout_guarded() -> None:
     
         assert "run_browser_install_with_timeout()" in text
         assert "run_browser_install_with_timeout 600 npx playwright install chromium" in text
    +    # --with-deps is still invoked on apt-based systems, but only when sudo
    +    # is available non-interactively (root or passwordless sudo). Non-sudo
    +    # service users fall back to the browser-only install — see
    +    # install_node_deps() in install.sh.
         assert "run_browser_install_with_timeout 600 npx playwright install --with-deps chromium" in text
    +
    +
    +def test_install_script_supports_skip_browser_flag() -> None:
    +    """--skip-browser (and --no-playwright alias) skips the Playwright install."""
    +    text = INSTALL_SH.read_text()
    +
    +    assert "--skip-browser|--no-playwright)" in text
    +    assert "SKIP_BROWSER=true" in text
    +    assert 'if [ "$SKIP_BROWSER" = true ]; then' in text
    +    assert "--skip-browser Skip Playwright/Chromium install" in text
    +
    +
    +def test_install_script_skips_with_deps_when_no_sudo() -> None:
    +    """Non-sudo users on apt distros must not block on an interactive sudo prompt."""
    +    text = INSTALL_SH.read_text()
    +
    +    # The apt branch must gate --with-deps behind a sudo capability check
    +    # (root or non-interactive sudo), otherwise the installer hangs for
    +    # service-user installs (systemd accounts, operator users, etc.).
    +    assert 'if [ "$(id -u)" -eq 0 ] || (command -v sudo >/dev/null 2>&1 && sudo -n true 2>/dev/null); then' in text
    +    assert "sudo npx playwright install-deps chromium" in text
    ```
  - `website/docs/getting-started/installation.md`

    ```diff
    @@ -132,6 +132,43 @@ If you want to clone the repo and install from source — for contributing, runn
     
     ---
     
    +## Non-Sudo / System Service User Installs
    +
    +Running Hermes as a dedicated unprivileged user (e.g. a `hermes` systemd service account, or any user without `sudo` access) is supported. The only thing on the install path that genuinely needs root is Playwright's `--with-deps` step, which `apt`-installs shared libraries (`libnss3`, `libxkbcommon`, etc.) used by Chromium. The installer detects whether sudo is available and gracefully degrades when it isn't — it will install the Chromium binary into the service user's own Playwright cache and print the exact command an administrator needs to run separately.
    +
    +**Recommended split (Debian/Ubuntu):**
    +
    +1. **One time, as an admin user with sudo**, install the system libraries Chromium needs:
    +   ```bash
    +   sudo npx playwright install-deps chromium
    +   ```
    +   (You can run this from anywhere — `npx` will fetch Playwright on the fly.)
    +
    +2. **As the unprivileged service user**, run the regular installer. It will detect the missing sudo, skip `--with-deps`, and install Chromium into the user's local Playwright cache:
    +   ```bash
    +   curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash
    +   ```
    +
    +   If you want to skip the Playwright step entirely — for example because you're running headless and don't need browser automation — pass `--skip-browser`:
    +   ```bash
    +   curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash -s -- --skip-browser
    +   ```
    +
    +3. **Make `hermes` available to the service user's shells.** The installer writes the launcher to `~/.local/bin/hermes`. System service accounts often have a minimal PATH that doesn't include `~/.local/bin`. Either add it to the user's environment, or symlink the launcher into a system location:
    +   ```bash
    +   # Option A — add to the service user's profile
    +   echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
    +
    +   # Option B — symlink system-wide (run as an admin)
    +   sudo ln -s /home/hermes/.hermes/hermes-agent/venv/bin/hermes /usr/local/bin/hermes
    +   ```
    +
    +4. **Verify:** `hermes doctor` should now run cleanly. If you get `ModuleNotFoundError: No module named 'dotenv'`, you're invoking the repo source `hermes` file (`~/.hermes/hermes-agent/hermes`) with system Python instead of the venv launcher (`~/.hermes/hermes-agent/venv/bin/hermes`) — fix step 3.
    +
    +The same pattern works on Arch (the installer uses pacman with the same sudo-detection logic), Fedora/RHEL, and openSUSE — those distros don't support `--with-deps` at all, so an administrator always installs the system libraries separately. The relevant `dnf`/`zypper` commands are printed by the installer.
    +
    +---
    +
     ## Troubleshooting
     
     | Problem | Solution |
    ```
- **#16343: fix(installer): add arm64 fallback for Playwright setup**. open
  - maintainer direction: category `uncategorized`; implication `needs_llm`
  - files: `scripts/install.sh`
- **#16395: fix(install): #16314 improve Playwright setup behavior on ARM64**. closed without merge
  - maintainer direction: category `superseded_by_pr`; implication `superseded`; refs `#25814`

## Fix status

- Merged to main in PR #25814 (cited above). No release data is tracked. Verify downstream.
- Fix last verified (merged) `2026-05-14`.
- Subsystem: `apps/bootstrap-installer`
