[GH-ISSUE #905] Dev server crashes with Unhandled 'error' event (ECONNRESET) when editing files #200

Closed
opened 2026-05-06 12:38:06 +02:00 by BreizhHardware · 4 comments

Originally created by @eashish93 on GitHub (Apr 25, 2026).
Original GitHub issue: https://github.com/cloudflare/vinext/issues/905

What happens

Dev server (bun dev) crashes intermittently while editing source files.
The crash is always an Unhandled 'error' event on a Socket with code
ECONNRESET, originating from Node internals only — no vinext or app
code in the stack:

Error: read ECONNRESET
at TCP.onStreamRead (node:internal/stream_base_commons:216:20)
Emitted 'error' event on Socket instance at:
at Socket.onerror (node:internal/streams/readable:1031:14)
at Socket.emit (node:events:508:28)
...
errno: -54, code: 'ECONNRESET', syscall: 'read'

When

Reliably while saving files in the editor, especially when the browser
is mid-request (e.g. RSC stream still flushing) and HMR triggers a
reload. The hint is that two requests just completed (compile: ...,
render: ...), then the next save kills the process.

Why it's a bug

ECONNRESET on a peer-closed socket is normal. It shouldn't crash the
process. Node defaults to throw on unhandled error events, so the
underlying server (HTTP/WS) needs to attach a no-op error handler,
or vinext should attach one at the layer where it owns the socket.

For comparison, Vite handles this in vite's HMR server, and Next.js
ships an 'error' handler on req.socket for the same reason.

Env

  • vinext:
  • Node: v25.2.1
  • Bun: <bun --version>
  • OS: macOS (darwin 25.3.0)

Repro

  1. bun dev
  2. Open the app in browser, navigate around
  3. Edit a source file rapidly (or save mid-navigation)
  4. Server crashes within ~10 saves with the trace above
Originally created by @eashish93 on GitHub (Apr 25, 2026). Original GitHub issue: https://github.com/cloudflare/vinext/issues/905 ## What happens Dev server (`bun dev`) crashes intermittently while editing source files. The crash is always an `Unhandled 'error' event` on a Socket with code `ECONNRESET`, originating from Node internals only — no vinext or app code in the stack: Error: read ECONNRESET at TCP.onStreamRead (node:internal/stream_base_commons:216:20) Emitted 'error' event on Socket instance at: at Socket.onerror (node:internal/streams/readable:1031:14) at Socket.emit (node:events:508:28) ... errno: -54, code: 'ECONNRESET', syscall: 'read' ## When Reliably while saving files in the editor, especially when the browser is mid-request (e.g. RSC stream still flushing) and HMR triggers a reload. The hint is that two requests just completed (`compile: ...`, `render: ...`), then the next save kills the process. ## Why it's a bug ECONNRESET on a peer-closed socket is normal. It shouldn't crash the process. Node defaults to `throw` on unhandled `error` events, so the underlying server (HTTP/WS) needs to attach a no-op error handler, or vinext should attach one at the layer where it owns the socket. For comparison, Vite handles this in vite's HMR server, and Next.js ships an `'error'` handler on `req.socket` for the same reason. ## Env - vinext: <fill in version from package.json> - Node: v25.2.1 - Bun: <bun --version> - OS: macOS (darwin 25.3.0) ## Repro 1. `bun dev` 2. Open the app in browser, navigate around 3. Edit a source file rapidly (or save mid-navigation) 4. Server crashes within ~10 saves with the trace above
Author
Owner

@james-elicx commented on GitHub (Apr 26, 2026):

I wasn't actually able to reproduce this in my local projects, but I had Claude scout through Next.js and figure out if they did anything that might help with HMR. Just merged a PR to no-op the socket errors which should help here.

<!-- gh-comment-id:4322817908 --> @james-elicx commented on GitHub (Apr 26, 2026): I wasn't actually able to reproduce this in my local projects, but I had Claude scout through Next.js and figure out if they did anything that might help with HMR. Just merged a PR to no-op the socket errors which should help here.
Author
Owner

@james-elicx commented on GitHub (Apr 26, 2026):

Hmph, I managed to get a crash to occur locally after that fix... Trying another more aggressive one...

<!-- gh-comment-id:4322879263 --> @james-elicx commented on GitHub (Apr 26, 2026): Hmph, I managed to get a crash to occur locally after that fix... Trying another more aggressive one...
Author
Owner

@james-elicx commented on GitHub (Apr 26, 2026):

argh. i no longer run into the crash in the original way i was able to reproduce it, but i've started running into it during navigating around the project i'm testing in...

<!-- gh-comment-id:4322917516 --> @james-elicx commented on GitHub (Apr 26, 2026): argh. i no longer run into the crash in the original way i was able to reproduce it, but i've started running into it during navigating around the project i'm testing in...
Author
Owner

@james-elicx commented on GitHub (Apr 26, 2026):

Alright. Think I finally got an actual fix.

Will do a release for it in the morning, but you can try a prerelease for the pr if you want to.

There will be a debug env var VINEXT_DEBUG_SOCKET_ERRORS=1 that you can use to log debug info for the flag as well which will log that it was initialised, and will log when it swallows the errors.

My second reproduction scenario was spamming around hundreds of different prefetched routes really fast and refreshing at the same time.

Managed to get it to log [vinext] absorbed uncaughtException ECONNRESET when trying to repro, which means the patch is now working as intended.

<!-- gh-comment-id:4323062646 --> @james-elicx commented on GitHub (Apr 26, 2026): Alright. Think I finally got an actual fix. Will do a release for it in the morning, but you can try a prerelease for the pr if you want to. There will be a debug env var `VINEXT_DEBUG_SOCKET_ERRORS=1` that you can use to log debug info for the flag as well which will log that it was initialised, and will log when it swallows the errors. My second reproduction scenario was spamming around hundreds of different prefetched routes really fast and refreshing at the same time. Managed to get it to log `[vinext] absorbed uncaughtException ECONNRESET` when trying to repro, which means the patch is now working as intended.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#200
No description provided.