Skip to content

fix(ci): BrowserOS neo release fails on macOS - pip install hits PEP 668 externally-managed-environment #2104

Description

Summary

The Release: BrowserOS neo (full) workflow fails on both macOS matrix legs because pip install --user boto3 is rejected by PEP 668 on the macos-14 runner image.

Because the release never completes, the download/BrowserOS_neo* "latest" aliases are never published to R2/CDN — so both download badges at the top of the README currently 404 for every visitor.

Evidence

Latest release attempt: run 30975212125 (2026-08-05).

Two jobs failed, on two independent runners, at the same step — so this is deterministic, not a flake:

Job ID Failing step
Prepare BrowserClaw server resources / Build / darwin-x64 92211393146 Recover existing immutable target
Prepare BrowserClaw server resources / Build / darwin-arm64 92211393165 Recover existing immutable target

Log output:

error: externally-managed-environment

× This environment is externally managed
╰─> To install Python packages system-wide, try brew install
    xyz, where xyz is the package you are trying to install.
    ...
##[error]Process completed with exit code 1.

Runner image: macos-14-arm64 / 20260629.0180.1, macOS 14.8.7.

The linux-x64 and windows-x64 legs of the same matrix passed — only macOS is affected, because there python3 resolves to Homebrew's Python, which is marked externally managed.

Root cause

.github/workflows/release-claw-server-rust.yml line 347:

      - name: Recover existing immutable target
        id: recover
        shell: bash
        run: |
          set -euo pipefail
          "$PYTHON_BIN" -m pip install --user boto3   # <-- fails on macos-14
          "$PYTHON_BIN" <<'PY'

PYTHON_BIN is set to python3 on every non-Windows runner by the Setup Python step (line 330-338). On macos-14 that is Homebrew Python, so pip install --user is refused per PEP 668.

This step was introduced two days ago:

211f94932  2026-08-04  fix(release): make BrowserOS releases deterministic (#2096)

git log -S 'pip install --user boto3' -- .github/workflows/release-claw-server-rust.yml confirms both the step and the pip install line arrived in that commit.

Impact

packages/browseros/bos_build/release/common.py:139-153 derives the CDN "latest" aliases from the product's artifact_prefix, and release/publish.py only writes them on a successful publish. Since #2090 set artifact_prefix="BrowserOS_neo", those aliases are:

download/BrowserOS_neo.dmg
download/BrowserOS_neo_installer.exe

Neither has ever been published, because no release has succeeded since the rebrand. Verified with HEAD requests:

URL Status
https://cdn.browseros.com/download/BrowserOS_neo.dmg 404
https://cdn.browseros.com/download/BrowserOS_neo_installer.exe 404
https://cdn.browseros.com/download/BrowserClaw.dmg 200 (from 0.48.1)
https://cdn.browseros.com/download/BrowserClaw_installer.exe 200 (from 0.48.1)

Those two 404 URLs are exactly what README.md lines 24-25 link to. The last successful claw release was 2026-07-29 (0.48.1), published under the old BrowserClaw prefix.

Suggested fix

uv is already installed by astral-sh/setup-uv two steps earlier (line 327), and the same file already uses it correctly at line 578. Using it here avoids touching the system interpreter entirely and works identically on macOS, Linux and Windows:

        run: |
          set -euo pipefail
          uv run --no-project --with boto3 python <<'PY'

I've confirmed no other step in that job needs boto3 — the remaining "$PYTHON_BIN" blocks (lines 421, 470, 500) import only stdlib modules — so removing the --user install has no downstream effect.

Related (not addressed here)

The same pip install --user pattern appears twice more in the file:

  • line 637 — python3 -m pip install --user boto3
  • line 781 — python3 -m pip install --user awscli

Both are on ubuntu-latest jobs, so they don't fail today, but they carry the same latent risk on a future runner image bump. Left alone to keep this fix minimal and reviewable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions