cube-js/cube · error · UserError
messageId is required
Error message
messageId is required
What it means
Validation guard in SubscriptionServer.handleMessage: a WebSocket message that is neither a handshake nor an unsubscribe must carry a `messageId` so responses can be correlated with subscriptions; this sentinel UserError fires when it is absent, and the error is sent back over the socket rather than crashing the connection.
Source
Thrown at packages/cubejs-api-gateway/src/ws/subscription-server.ts:137
const acceptanceResult = await this.contextAcceptor(authContext);
if (!acceptanceResult.accepted) {
this.sendMessage(connectionId, acceptanceResult.rejectMessage);
return;
}
await this.subscriptionStore.setAuthContext(connectionId, authContext);
this.sendMessage(connectionId, { handshake: true });
return;
}
if ('unsubscribe' in message) {
await this.subscriptionStore.unsubscribe(connectionId, message.unsubscribe);
return;
}
if (!message.messageId) {
throw new UserError('messageId is required');
}
authContext = await this.subscriptionStore.getAuthContext(connectionId);
if (!authContext) {
await this.sendMessage(
connectionId,
{
messageId: message.messageId,
message: { error: 'Not authorized' },
status: 403
}
);
return;
}
if (!message.method) {
throw new UserError('Method is required');
}View on GitHub (pinned to 7d981676b3)
Solutions
- Include a unique messageId string in every subscription message sent over the WebSocket.
- Check that the client SDK serializes the message correctly and does not drop messageId.
Example fix
// before
socket.send(JSON.stringify({ method: 'load', query }));
// after
socket.send(JSON.stringify({ messageId: 'q-1', method: 'load', query })); Defensive patterns
Strategy: validation
Validate before calling
function assertMessageId(msg: { messageId?: string }) {
if (!msg.messageId) {
throw new Error('messageId is required');
}
} Type guard
function hasMessageId(m: unknown): m is { messageId: string } {
return typeof m === 'object' && m !== null && typeof (m as any).messageId === 'string' && (m as any).messageId.length > 0;
} Try / catch
try {
await handleMessage(frame);
} catch (e) {
if (e instanceof UserError && e.message === 'messageId is required') {
console.error('Outgoing WS frame missing messageId:', frame);
} else throw e;
} Prevention
- Attach a unique messageId to every WS request before sending.
- Reuse the same messageId when unsubscribing from a subscription.
- Rely on WebSocketTransport, which generates message ids automatically.
- Add a serialization helper that enforces messageId presence for all frames.
When it happens
Trigger: Sending a WS request object without a messageId key, an empty string, or undefined value
Common situations: Custom WS clients omitting messageId; copying protocol examples that lacked it; race where subscribe is issued before setting an id.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Invalid unsubscribe message format
- Invalid message format
- Method is required
- Invalid JSON payload
- Invalid authorization message format
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/11f06abfe455d283.
Report an issue: GitHub.