-
-
Notifications
You must be signed in to change notification settings - Fork 744
WebSocketStream sometimes mixes non-message bytes into opened.readable #4958
Copy link
Copy link
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
Bug Description
WebSocketStream occasionally yields chunks from opened.readable that are not WebSocket message payloads.
In our case, the server sends JSON text frames, but the client sometimes receives chunks prefixed with unexpected bytes (looks like raw frame/socket data), for example:
�"{"event":"Initialize","data":1010}
This causes JSON.parse() to fail with:
SyntaxError: Unexpected token '�'
The issue reproduces against a local mock WebSocket server.
Reproducible By
- Start a local WebSocket server that sends two JSON text messages immediately after each connection.
// bench/mock-ws-server.ts
import { WebSocketServer } from "ws";
const port = 19876;
const wss = new WebSocketServer({
port,
path: "/",
perMessageDeflate: false,
});
let nextId = 1000;
wss.on("connection", (socket) => {
const id = nextId++;
socket.send(JSON.stringify({ event: "Initialize", data: id }));
socket.send(JSON.stringify({ event: "Ready", data: { id } }));
});- Run a
WebSocketStreamclient loop that readsopened.readableand parses each chunk as JSON.
// bench/repro-undici-wss.ts
import { WebSocketStream } from "undici";
const WS_URL = "ws://localhost:19876/";
for (let i = 1; i <= 500; i++) {
const wss = new WebSocketStream(WS_URL);
const { readable } = await wss.opened;
const reader = readable.getReader();
for (let j = 0; j < 2; j++) {
const next = await reader.read();
if (next.done) break;
const raw = String(next.value);
JSON.parse(raw);
}
reader.releaseLock();
wss.close();
await wss.closed.catch(() => {});
}- Execute:
node bench/mock-ws-server.ts
node bench/repro-undici-wss.tsExpected Behavior
opened.readable should yield complete message payloads only. For text frames, each chunk should be valid text payload data and parse as expected.
Logs & Screenshots
Observed output from reproduction:
[run 11] malformed chunk detected
prefix="�\"{\"event\":\"Initialize\",\"data\":1010}"
codes=65533,34,123,34,101,118,101,110,116,34,58,34
Also observed intermittently in the same short-lived connection workload:
TypeError [ERR_INVALID_STATE]: Invalid state: Controller is already closed
at .../websocketstream.js:395:38
Environment
- OS:
Darwin 25.3.0 (arm64) - Node:
v24.12.0 undicipackage version:7.24.6(still exists on8.0.0)process.versions.undici:7.16.0
Additional context
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working