Ace installation can silently leave an incomplete Puppeteer browser cache on recent Node.js versions
- Dominant language
- JavaScript
- Stars
- 98
- Forks
- 29
- PR merge metrics
- No merged PRs in 30d
Description
## Problem
`@daisy/ace@1.4.6` installs Puppeteer 24 via `@daisy/ace-axe-runner-puppeteer`. The Ace test suite also uses Puppeteer 24 via `@daisy/jest-env-puppeteer`.
On affected Node.js versions, extraction of a valid browser ZIP through Puppeteer's transitive `extract-zip`/`yauzl` dependency chain can stop partway, leaving the extraction Promise neither resolved nor rejected. `npm` may still report a successful install while the Puppeteer cache contains only a partially extracted browser and no executable.
Later installation attempts fail because the versioned browser directory exists but its expected executable is missing. Because the cache is outside npm's package rollback, they continue to fail until the user removes the incomplete browser directory or cache.
## Affected environments
I reproduced this with `@daisy/ace@1.4.6` in both of the following environments:
- Windows 11 Pro 25H2 x64, Node.js 24.17.0, npm 11.17.0
- macOS 26.5.2 arm64, Node.js 24.17.0, npm 11.13.0
By contrast, on the same macOS system, Node.js 24.15.0 produced a complete browser cache with both expected executables (npm 12.0.1, with the required dependency install scripts allowed).
## User-visible failure
A later installation attempt reports an error such as:
The browser folder
(.../.cache/puppeteer/chrome-headless-shell/...)
exists but the executable
(.../chrome-headless-shell)
is missing
Ace normally uses its Electron runner by default, but Puppeteer is still installed and its browser postinstall runs during package installation. Users can therefore encounter this problem without explicitly selecting the Puppeteer runner.
Because Puppeteer's default cache is shared across package installations, the failure may surface while installing a different package whose Puppeteer dependency uses the same cached browser revision.
## Cause
The dependency path in the affected installation was:
@daisy/ace@1.4.6
-> @daisy/ace-cli@1.4.6
-> @daisy/ace-axe-runner-puppeteer@1.4.6
-> puppeteer@24.43.1
-> @puppeteer/browsers@2.13.2
-> extract-zip@2.0.1
-> yauzl@2.10.0
This matches the regression reported in `extract-zip` issue [#154](https://github.com/max-mapper/extract-zip/issues/154) and Puppeteer issue [#14957](https://github.com/puppeteer/puppeteer/issues/14957). The underlying `yauzl` stream handling was fixed by yauzl PR [#170](https://github.com/thejoshwolfe/yauzl/pull/170) and released in `yauzl` 3.3.1, but `extract-zip@2.0.1` still depends on `yauzl` 2.x. Puppeteer moved away from this `extract-zip` dependency path in PR [#14960](https://github.com/puppeteer/puppeteer/pull/14960).
## Potential resolution
I tested updating both of Ace's direct Puppeteer dependencies to `puppeteer@25.3.0` in a local Ace branch. No Ace source changes were required, and the following checks succeeded on Windows with Node.js 24.17.0:
- installation into a clean Puppeteer cache, including both browser downloads;
- the full Ace monorepo build;
- the Puppeteer-based Jest tests;
- Ace CLI processing of a sample EPUB and report generation.
Puppeteer 25 requires Node.js 22.12.0 or later, while Ace currently declares support for Node.js 20 or later.
---
Additional testing confirmed that Node.js 24.18.0 and 24.18.1 successfully complete browser extraction with the same Puppeteer dependencies. For users affected on Node.js 24.16.0 or 24.17.0, a workaround is to upgrade Node.js and **remove any incomplete browser directory identified in the error before reinstalling**. Upgrading Node.js alone does not repair an already incomplete cache.
The same failure still reproduces on Node.js 26.8.2, so updating Ace’s affected dependency chain remains relevant. See [nodejs/node#63834](https://github.com/nodejs/node/pull/63834) for the Node.js 24 revert.
Contributor guide
Research direction
Inspect Ace's direct Puppeteer dependency declarations first; the issue does not name the manifest files. Update both affected dependencies to the tested Puppeteer version, then run a clean installation with browser downloads, the full Ace monorepo build, the Puppeteer-based Jest tests, and Ace CLI processing of a sample EPUB. Done means the browser cache contains both executables and all listed checks pass while the supported Node.js range is considered.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, node.js
- Domain
- build-system, testing
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100