Repository navigation
Conversation
Node 24.15+ bundles undici 7.x, whose HTTP/1.1 writer calls socket.setTypeOfService() on each new socket's first request without a try/catch, and Node's net throws on any non-Windows setsockopt failure. On macOS setsockopt returns EINVAL once the peer has reset the connection, so one fetch whose connection is reset before the request is written throws from the socket connect callback as an uncaught exception and exits the whole process instead of rejecting that fetch. undici fixed this in v8.8.0 (nodejs/undici#5547), but it was never backported to v7.x. Every Node 24 release through 24.21.0 and every Electron line through 46 nightly still ship the unguarded call, so bumping Electron cannot fix it. Install a narrow guard in the host daemon and server entrypoints that ignores EINVAL from setTypeOfService; the request then continues, fails writing to the reset socket, and rejects its own promise. The guard is a no-op on runtimes without the API (Node 22) and becomes inert once undici stops calling it by default. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ymichael
deleted the
bb/high-priority-host-daemon-crashes-daily-on-macos-thr_nzeqgckxvy
branch
October 1, 2026 18:14
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Human comments
What was wrong
Node 24.15+ added
net.Socket#setTypeOfService, and the undici 7.x it bundles callssocket.setTypeOfService(0)fromwriteH1on every new socket's first request without a try/catch. Node'snetthrows on any setsockopt failure except on Windows. On macOS, setsockopt returnsEINVALonce the peer has reset the connection, so one fetch whose connection is reset before the request is written throws from the socket connect callback as anuncaughtException. The fetch promise is never rejected, and the whole host daemon or server exits, interrupting every running turn on the host.Upstream fixed this in nodejs/undici#5547 (released in undici 8.8.0+, bundled in Node 26.5.1+), but it was never backported to undici 7.x. Every Node 24 release through 24.21.0 is affected, and every Electron line through the 46 nightlies still ships Node 24. bb 0.44's Electron 44.3.0 has Node 24.20.0 / undici 7.29.0. Bumping Electron cannot fix it. Node 22 has no
setTypeOfService, so dev machines on nvm Node 22 never see it.What changed
packages/process-utils: newinstallSocketTypeOfServiceGuard()wrapsnet.Socket.prototype.setTypeOfServiceand ignores onlyEINVAL. The request then continues, fails writing to the reset socket, and rejects its own promise withfetch failed. On runtimes without the API (Node 22) it does nothing, and it becomes inert once undici stops making the call by default.apps/host-daemon/src/index.tsandapps/server/src/index.tsinstall it next toinstallSafeProcessDiagnostics. The server was exposed too (macOS BB 0.43.4: recurrent host-daemon and server exits from uncaught Node/UndicisetTypeOfService EINVAL#4280 recorded 6 server crashes with the same stack); this also covers the in-process plugins that bundle npm undici 7.28 (account-pool, push-notifications).HOST_DAEMON_PROTOCOL_VERSIONis unchanged.Alternatives considered: no fixed Node 24 or Electron release exists to bump to. Routing all fetches through an npm undici v8 dispatcher also prevented the crash in testing, but it would move every fetch in the process to a different undici major, add a runtime dependency, and not cover plugins that bundle their own undici.
Not covered: plugin host workers and provider bridges run as separate Node processes and don't install the guard. A crash there restarts that worker, not the daemon.
How you verified
net:911,undici:8022/7758/9656/9589/9370/3342). Even with no stall it crashed 50–75% of runs. On Node 22 the same fetch rejects with EPIPE. With the guard, 20/20 runs rejected withfetch failed.process-host-daemon-uncaughtException-*.json(v24.20.0).packages/process-utils/test/socket-type-of-service.test.ts:setTypeOfService, so it is skipped in CI (Node 22). On Node 24.20 it passes with the guard and fails with the guard removed (Unhandled Error: setTypeOfService EINVAL).pnpm exec turbo run typecheck lint --filter=@bb/process-utils --filter=@bb/host-daemon --filter=@bb/serverandturbo run testfor@bb/process-utilsand@bb/host-daemonpass.Fixes #4280
🤖 Generated with Claude Code