Skip to content

browse connect (headed) fails: setup installs wrong Chromium revision vs compiled binary's pinned Playwright #1829

@antoniodavila

Description

@antoniodavila

Summary

On a clean install/upgrade, browse connect (headed) fails with Executable doesn't exist at .../ms-playwright/chromium-1208/... even though ./setup reported success and headless browse works fine. Root cause: the version of Playwright that ./setup uses to install browsers is resolved at runtime (latest) and downloads a different Chromium revision than the one embedded in the compiled browse binary, and the post-install verification only launches headless, so the mismatch is never caught.

Environment

  • gstack 1.55.0.0 (also reproduced on 1.28.0.0 before upgrading)
  • macOS arm64, Node v26.0.0, Bun 1.3.11
  • Install type: global-git (~/.claude/skills/gstack)

What happens

$ browse connect
Launching headed Chromium with extension + terminal agent...
[browse] Connect failed: Server failed to start:
persistentContext: Executable doesn't exist at
  ~/Library/Caches/ms-playwright/chromium-1208/chrome-mac-arm64/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing
    at async launchHeaded (browse/src/browser-manager.ts:557:35)
    at async start (browse/src/server.ts:2938:28)

Headless browse (e.g. /qa headless, goto, snapshot) works perfectly the whole time.

Playwright cache after a fresh ./setup:

chromium_headless_shell-1208   <- present (why headless works)
chromium_headless_shell-1223
chromium-1223                  <- full build, WRONG revision
ffmpeg-1011
# chromium-1208 (full) is MISSING -> headed fails

Root cause

  1. The compiled browse binary (bun --compile) embeds a pinned Playwright that resolves Chromium revision 1208 (Chrome for Testing 145.0.7632.6, Playwright 1.58.2).
  2. setup installs browsers with bunx playwright install chromium (setup ~line 483), which resolves latest Playwright at runtime (currently 1.60.0 -> revision 1223). So it downloads the wrong full build.
  3. ensure_playwright_browser() (setup ~line 252) verifies with a headless launch:
    bun --eval 'import { chromium } from "playwright"; const browser = await chromium.launch(); await browser.close();'
    This passes because chromium_headless_shell-* is present, so the missing full build (needed by launchHeaded) is never detected.

Net: setup's installer Playwright and the compiled binary's Playwright are not the same version, and the verify step only exercises headless. Headed users are broken on a "successful" install.

Workaround (confirmed fix)

Install the full Chromium at the revision the compiled binary pins:

bunx playwright@1.58.2 install chromium   # downloads chromium-1208 full (~162MB)
browse connect                            # -> Mode: headed  ✅

Suggested fix

  • Install browsers using the same Playwright version embedded in the compiled browse binary, not a runtime-resolved latest. e.g. pin playwright@<bundled-version> in the setup install step, or expose browse install-browsers that shells out to the binary's own embedded Playwright so install and runtime can never drift.
  • Make ensure_playwright_browser() launch headed (or assert the full Chrome-for-Testing executable path exists), so a missing full build fails setup instead of being masked by the cached headless shell.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions