fix: override yauzl to 3.3.1 to fix Electron postinstall hang on Node 24.16.0+#3584
Conversation
…Node 24.16.0+ fd-slicer's custom destroy() collides with Node 24.16.0's stream lifecycle change, causing extract-zip to silently hang at 97% during Electron binary extraction. yauzl 3.x drops fd-slicer entirely. extract-zip is unmaintained and pins yauzl ^2.10.0, so the fix can only flow through a pnpm override. Refs: thejoshwolfe/yauzl#170, nodejs/node#63487
|
Hey @jeremeioss, that's the one — and the writeup is exceptional. The layer-by-layer isolation (fs → InflateRaw works, fd-slicer → PassThrough works, fd-slicer → InflateRaw hangs) plus the cites to nodejs/node#63487, yauzl#170, and the VS Code precedent make the Routed to @nettee from the review pool. Labeled |
nettee
left a comment
There was a problem hiding this comment.
@jeremeioss I verified that this override stays aligned with the current dependency graph: in this lockfile it only replaces Electron's extract-zip -> yauzl path, removes fd-slicer from that install chain, and keeps the package metadata and lockfile changes consistent for the Node 24 postinstall fix. Thanks for tracking down a subtle transitive dependency failure and keeping the remediation tight.
🎉 📡 You just leveled up to Giotto
🙌 Your contributions send a clear signal across the network: you care about making Open Design better. 💛 Thanks for helping Open Design move forward. Keep building in the open. 🚀 📊 Rank #198 among 198 contributors. |
|
Hi @jeremeioss! Your first Open Design PR has been merged! Huge thanks for jumping in and improving the project! You contributed: Merged PR: #3584 fix: override yauzl to 3.3.1 to fix Electron postinstall hang on Node 24.16.0+ You fixed a packaging/install reliability problem at the dependency layer, which is exactly the sort of low-visibility work that saves people from painful setup failures. That makes you a strong fit for other desktop and install-adjacent cleanup. For your next contribution, we picked two issues that look like a good follow-up:
This stays in the desktop packaging/distribution surface and is a concrete user-facing fix with a clear reproduction area.
This is another install/management-adjacent task that benefits from comfort around app packaging and local environment behavior. If one of these looks interesting, feel free to comment /claim on the issue and we will help you get started! Once your second PR gets merged, you will move into our Continuous Contributor tier. We are also starting to highlight repeat contributors more actively in the community, so this is a great time to keep going! Thanks again for the first PR, and welcome to the Open Design contributor community! The Open Design team P.S. We hang out in Discord — come say hi: https://discord.gg/3C6EWXbdQQ |
















































Discovered while testing linux appimage build as part of this closed issue
Reported in this comment
Why
Running
pnpm tools-pack linux build --to appimageon Node ≥ 24.16.0 failswith:
electron-buildertries to rename the extracted Electron binary, but itdoesn't exist because Electron's postinstall silently produced a broken
runtime:
electron/dist/contains onlyv8_context_snapshot.bin— no binary,no
locales/, noresources/. The postinstall script exits 0 with no error orwarning.
Root cause
Electron's
install.jsusesextract-zip→yauzl→fd-slicerto extractthe downloaded binary zip.
fd-slicer@1.1.0implements its owndestroy()onReadStream, dating back to before Node 8 added a nativeReadable.destroy().These two implementations collide with a stream-lifecycle change introduced in
Node 24.16.0 (nodejs/node#63487).
When
zlib.createInflateRaw()applies backpressure during decompression, Node24's stream internals interact with
fd-slicer's brokendestroyin a way thatprevents the Readable from ever resuming. The raw stream stops after exactly 3
read operations (196,608 / 204,997 bytes), and inflation stalls at 97% (694,688
/ 715,208 bytes). No error event, no close event, no rejection — a silent hang.
This was confirmed by testing each layer in isolation:
fs.createReadStream→InflateRawworks fine;fd-slicerReadStream →PassThroughworks fine;fd-slicerReadStream →InflateRawhangs. The issue is specific to customJavaScript Readables with async
_readpiped into zlib on Node ≥ 24.16.0.Why a pnpm override
yauzl@3.3.1([thejoshwolfe/yauzl#170]) fixes this by droppingfd-slicerentirely — it only depends on
pend. However,extract-zip@2.0.1(used byElectron's installer) pins
yauzl@^2.10.0and has been unmaintained for 6 years(max-mapper/extract-zip#154), so the fix cannot flow through normal dependency
resolution. A pnpm override is the same approach used by VS Code
(microsoft/vscode#318682) and other projects hitting the same issue.
What users will see
No visible UI change. Users building the packaged app on Node ≥ 24.16.0 will
find that
pnpm tools-pack linux build(and the equivalent macOS/Windowspaths) now complete successfully instead of silently producing a broken Electron
runtime.
Surface area
apps/weborapps/desktop(including Electron menu bar)odsubcommand or flag, newtools-dev/tools-pack/tools-prflag, or newOD_*env var/api/*endpoint, new SSE event, or changed shape inpackages/contractsskills/,design-systems/,design-templates/, orcraft/, or change to the skills protocolTRANSLATIONS.mdfor the locale workflow)package.json(dependenciesordevDependencies); workspace-packagepackage.jsonfiles are out of scope. Include a paragraph on what we get vs. what bytes we ship (seeCONTRIBUTING.md→ Code style)New top-level dependency note: This is not a new dependency — it is a pnpm
override that forces all transitive
yauzlresolution to the fixed3.3.1.No new package enters the dependency tree; existing
yauzl@2.10.0instances(from
extract-zip→yauzl) are replaced in-place.Screenshots
Not applicable — no UI change.
Bug fix verification
The bug is a silent hang in a transitive dependency during postinstall, which
is not easily reproducible in a unit test. Verification was done by:
electron/dist/is empty (onlyv8_context_snapshot.bin) onNode 24.16.0 without the override.
pnpm install, and confirmingelectron/dist/now contains the full runtime (binary,
locales/,resources/,libffmpeg.so, etc.).pnpm tools-pack linux build --to appimageend-to-end successfully.Validation