Skip to content

Websockets object identity is not stable across open/message/close hooks #1716

@erfanmola

Description

@erfanmola

What version of Elysia is running?

1.4.22

What platform is your computer?

Darwin 25.2.0 arm64 arm

What environment are you using

1.3.8

Are you using dynamic mode?

No response

What steps can reproduce the bug?

In Elysia’s WebSocket implementation (Bun adapter), the ws object passed to the open, message, and close handlers is not the same JavaScript instance.

Although it represents the same underlying native socket, Elysia appears to wrap it in a new JS proxy per lifecycle hook. This makes identity-based comparisons unreliable:

storedWs === wsFromClose // false

This breaks common patterns such as:

  • Tracking active sockets in a Map / Set
  • Cleaning up connections on close
  • Per-socket state storage
  • Matching sockets by reference

Sample Code to test:

import { Elysia } from "elysia";
import { randomUUID } from "crypto";

new Elysia()
	.ws("/ws", {
		open(ws) {
			const id = randomUUID();
			(ws as any)._id = id;

			console.log("OPEN wrapper:", ws);
			console.log("OPEN id:", id);
		},

		message(ws, message) {
			console.log("MESSAGE wrapper === OPEN wrapper?", (ws as any)._id);
			ws.send("ok");
		},

		close(ws, code, reason) {
			console.log("CLOSE wrapper:", ws);
			console.log("CLOSE id:", (ws as any)._id);
		},
	})
	.listen(2000);

console.log("WS server on ws://localhost:2000/ws");

What is the expected behavior?

Work like bun own websockets:

const server = Bun.serve({
	port: 3001,

	fetch(req, server) {
		if (server.upgrade(req)) return;
		return new Response("Upgrade to WS", { status: 426 });
	},

	websocket: {
		open(ws) {
			(ws as any)._id = Math.random();
			console.log("OPEN id:", (ws as any)._id, ws);
		},

		message(ws, message) {
			console.log("MESSAGE id:", (ws as any)._id, ws);
			ws.send("ok");
		},

		close(ws, code, reason) {
			console.log("CLOSE id:", (ws as any)._id, ws);
		},
	},
});

console.log("Bun WS server on ws://localhost:3001");

What do you see instead?

No response

Additional information

No response

Have you try removing the node_modules and bun.lockb and try again yet?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions