Skip to content

Commit 5a9a09d

Browse files
B4nanclaude
andauthored
ci: skip puppeteer postinstall download to avoid Chrome race on Node 24 (#912)
## What Set `PUPPETEER_SKIP_DOWNLOAD=1` on the `pnpm install` step in the `Build & Test` matrix, so puppeteer's postinstall doesn't try to download Chrome. The dedicated `Install Chrome for puppeteer` step (already in the workflow) keeps doing the download synchronously and reliably. ## Why Node 24 jobs have been failing intermittently with: ``` BrowserLaunchError: Failed to launch browser Caused by: Could not find Chrome (ver. 146.0.7680.153). ``` Step timing shows the `Install Chrome for puppeteer` step has been silently no-opping on Node 24 — exiting in ~1 s with no output, vs ~4 s with a `chrome@146.0.7680.153 …` line on a healthy run. ### Root cause Puppeteer's postinstall hook ([`install.mjs`](https://github.com/puppeteer/puppeteer/blob/puppeteer-v24.40.0/packages/puppeteer/install.mjs)) is **fire-and-forget**: ```js const {downloadBrowsers} = await importInstaller(); downloadBrowsers(); // ← not awaited ``` Inside, `downloadBrowsers()` kicks off downloads for chrome, chrome-headless-shell, and firefox in parallel. When `pnpm install` returns before they finish, the process is reaped mid-download and `~/.cache/puppeteer/chrome/linux-146.0.7680.153/` is left half-populated. The next step then runs `pnpm exec puppeteer browsers install chrome`, which hands off to `@puppeteer/browsers`. That library's "already installed" check is purely "does this directory exist with the right buildId?" — so it sees the half-written directory, assumes Chrome is installed, and exits silently. Tests then explode at runtime because the binary isn't actually there. That explains everything we observed: - **Only Node 24** — probably just timing; Node 24's faster startup loses the race more often. - **Intermittent** — it's a literal race between `pnpm install` returning and the download completing. - **Retries sometimes work** — when the download happens to finish in time, no orphaned directory, all green. - **Has been a slow-burn issue** — but the Renovate/TS-v6 lockfile bumps that invalidate the pnpm-store cache made the race lose more often. ### Fix `PUPPETEER_SKIP_DOWNLOAD=1` on the install step makes puppeteer's postinstall log "Skipping downloading browsers as instructed" and return immediately — no racy background download, no orphaned cache directory. The explicit step that follows then performs the download synchronously and reliably. Credit to @barjin for [suggesting this approach](#912 (comment)) — it's much cleaner than the `rm -rf ~/.cache/puppeteer` workaround in the first commit, which only mopped up after the race instead of preventing it. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 0536f90 commit 5a9a09d

1 file changed

Lines changed: 10 additions & 0 deletions

File tree

.github/workflows/check.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@ jobs:
4141

4242
- name: Install pnpm and dependencies
4343
uses: apify/actions/pnpm-install@v1.1.2
44+
env:
45+
# Puppeteer's postinstall kicks off the Chrome download in a
46+
# fire-and-forget Promise (downloadBrowsers() is not awaited
47+
# in puppeteer's install.mjs). When pnpm install returns
48+
# before the download finishes, ~/.cache/puppeteer is left
49+
# half-populated, and the subsequent `browsers install`
50+
# silently no-ops because the directory already exists.
51+
# Skip the postinstall download entirely and let the explicit
52+
# step below do it synchronously.
53+
PUPPETEER_SKIP_DOWNLOAD: 1
4454

4555
- name: Install Chrome for puppeteer
4656
run: pnpm exec puppeteer browsers install chrome

0 commit comments

Comments
 (0)