clockworklabs/SpacetimeDB · error · RangeError
v3 websocket payloads must contain at least one message
Error message
v3 websocket payloads must contain at least one message
What it means
SpacetimeDB's v3 WebSocket protocol batches one or more BSATN-encoded server messages into each binary frame. forEachServerMessageV3 refuses to process a frame whose payload is empty (reader.remaining === 0) because a v3 frame must contain at least one message; an empty buffer indicates malformed framing, not a legitimate (empty) batch.
Source
Thrown at crates/bindings-typescript/src/sdk/websocket_v3_frames.ts:117
ClientMessage.deserialize(reader)
);
}
export function encodeServerMessagesV3(
writer: BinaryWriter,
messages: readonly Uint8Array<ArrayBuffer>[]
): Uint8Array<ArrayBuffer> {
return concatenateMessagesV3(writer, messages);
}
export function forEachServerMessageV3(
reader: BinaryReader,
data: Uint8Array,
visit: (message: ServerMessage) => void
): number {
reader.reset(data);
if (reader.remaining === 0) {
throw new RangeError(EMPTY_V3_PAYLOAD_ERR);
}
let count = 0;
while (reader.remaining > 0) {
visit(ServerMessage.deserialize(reader));
count += 1;
}
return count;
}
View on GitHub (pinned to 524b4487d9)
Solutions
- Align the client SDK and spacetimedb server versions so both implement the same v3 framing
- If you pump frames yourself (custom WebSocketFactory or tests), skip zero-length frames instead of passing them to forEachServerMessageV3
- Capture raw frames (browser devtools or a logging WebSocketFactory) to identify which side produces the empty payload
- If an unmodified server sends empty frames against a matching SDK version, file a bug with the frame capture and host version
Defensive patterns
Strategy: validation
Validate before calling
function hasV3Messages(frame: Uint8Array): boolean {
return frame.byteLength > 0;
}
// in a custom transport/test pump:
if (!hasV3Messages(frame)) return; // skip empty frame instead of throwing Try / catch
In custom transports, wrap forEachServerMessageV3 in try/catch for RangeError, log the frame length, and drop the malformed frame rather than killing the connection.
Prevention
- Keep SDK and server versions aligned so v3 framing matches
- Skip zero-length frames in any custom WebSocketFactory before handing data to the SDK
- Add frame-level logging in development to catch malformed batches early
When it happens
Trigger: The server (or a custom WebSocketFactory/transport feeding the SDK) delivers a zero-length data frame to the v3 message pump; also reachable when calling forEachServerMessageV3 directly with an empty Uint8Array, e.g. in hand-written tests or a custom transport loop.
Common situations: Version skew where a newer host changes framing or emits keepalive/empty frames the SDK doesn't expect; unit tests constructing frames by hand; middleware that drops or splits frame payloads.
Related errors
- cannot serialize refs without a typespace
- could not serialize result: object had neither a `ok` nor an
- Could not serialize sum type; unknown tag ${value.tag}
- Brotli compression is not supported by the runtime. Please c
- Unexpected Compression Algorithm. Please use `gzip` or `none
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/72ac606012737284.
Report an issue: GitHub.