π Bug Report β Vite support: "Message is too large" in WebSocket
frandiox opened this issue Β· comments
Hi π
I'm trying to run Vite in workerd with a similar setup to this. It basically sends code to run in workerd (with dev-only AsyncFunction constructor) via WebSockets.
With a non-trivial app, I'm seeing the following error:
workerd/jsg/util.c++:281: error: e = kj/compat/http.c++:5681: failed: WebSocket protocol error; protocolError.statusCode = 1009; protocolError.description = Message is too large: 5445094 > 1048576
stack: 1019081e0 101908427 102b3833f 10118a324 10192437c 10136b05f; sentryErrorContext = jsgInternalError
Which seems to come from here in capnproto. It looks like WebSocket messages are quite limited, which might be OK for real apps but it's too small for running Vite.
Is there anyway to get around this? There was a similar fix for devtools websockets but it seems it doesn't affect in-app websockets. -- Maybe websocket.receive()
could be more generous if unsafeEvalBinding
is enabled?
Thanks!
Turns out the message was so big due to inlined sourcemaps. If this is a setting hard to change, we might be able to use fetch
instead of WS for this kind of messages π
The problem with increasing this limit for Worker apps is there's currently no way to stream a large message gradually. You can only receive a single whole ArrayBuffer or string representing the message in contiguous memory. Since Workers typically have a memory limit of 128MB, multi-megabyte buffers are problematic.
Arguably this line of reasoning doesn't really apply to workerd
, especially for dev-oriented use cases, but we're hesitant to make workerd
behave differently since it may confuse people when they go to deploy their app later.
The ideal fix to this is to add an alternative way to receive messages where large messages can be delivered as ReadableStreams. But, there's some engineering work needed to build that.
Do you control this protocol? Is it at all possible to split large messages into multiple pieces?
I see, thanks for checking this!
Do you control this protocol? Is it at all possible to split large messages into multiple pieces?
It looks like we have enough flexibility in the latest Vite beta to do different things for different types of messages:
- Keep using WS for HMR events, which have a smaller payload.
- Use unidirectional
fetch
to retrieve code and sourcemaps.
Therefore, we can keep the current limit for WS since HMR events should be <1MB π
Thanks!