cube-js/cube · error · QueryError
Cube Store missed message id: ${httpMessage.messageId()}
Error message
Cube Store missed message id: ${httpMessage.messageId()} What it means
When a message arrives on the WebSocket, the driver looks up a resolver in webSocket.sentMessages by messageId; if none exists the response is unknown and the driver throws a QueryError. This indicates the reply does not match any outstanding request — a protocol desynchronization between Cube and Cube Store.
Source
Thrown at packages/cubejs-cubestore-driver/src/WebSocketConnection.ts:384
// eslint-disable-next-line no-restricted-syntax
for (const key of Object.keys(webSocket.sentMessages)) {
webSocket.sentMessages[key].reject(e);
}
}
}, this.retryWaitTime());
}
if (webSocket === this.webSocket) {
this.webSocket = null;
}
});
webSocket.on('message', async (msg: Buffer) => {
const buf = new flatbuffers.ByteBuffer(msg);
const httpMessage = HttpMessage.getRootAsHttpMessage(buf);
const resolver = webSocket.sentMessages[httpMessage.messageId()];
if (!resolver) {
throw new QueryError(`Cube Store missed message id: ${httpMessage.messageId()}`);
}
delete webSocket.sentMessages[httpMessage.messageId()];
if (httpMessage.commandType() === HttpCommand.HttpError) {
resolver.reject(new QueryError(`${httpMessage.command(new HttpError())?.error()}`));
this.closeIfDrained(webSocket);
return;
}
try {
const nativeResMsg = await parseCubestoreResultMessage(msg);
resolver.resolve(nativeResMsg);
} catch (e) {
resolver.reject(e);
}
this.closeIfDrained(webSocket);View on GitHub (pinned to 7d981676b3)
Solutions
- Restart the connection/driver to resynchronize the message protocol
- Check for Cube Store restarts or multiple clients sharing one connection
- Align Cube Store and driver versions
- Capture logs (messageId) and report if reproducible with matching versions
Defensive patterns
Strategy: retry
Validate before calling
// cannot pre-validate server-initiated message ids; ensure single owner of the socket
if (!driver) throw new Error('driver not initialized'); Type guard
const isMissedMessage = (e) => /Cube Store missed message id/.test(e?.message ?? '');
Try / catch
try {
return await driver.query(sql, params);
} catch (e) {
if (isMissedMessage(e)) {
await reconnectDriver(); // resynchronize the protocol
return driver.query(sql, params);
}
throw e;
} Prevention
- Never share one WebSocketConnection across multiple client processes
- Detect Cube Store restarts and proactively reconnect
- Keep driver and Cube Store versions in sync
- Avoid duplicated-delivery intermediaries on the socket path
When it happens
Trigger: Cube Store sends a message whose id was never sent by the driver, a duplicate response, or a late response whose resolver entry was already deleted; typically after reconnects or a server restart mid-connection.
Common situations: Cube Store process restart while the client keeps the socket; duplicated messages through proxies; internal driver/server message-id mismatches on version skew.
Related errors
- Empty response on QUEUE ${command}
- Cube Store connection is closed
- Cube Store request size of ${formatSize(buffer.length)} exce
- Cube Store response size exceeds the maximum message size of
- Request of {} bytes exceeds the maximum message size of {} b
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/9c325cf02cba7cba.
Report an issue: GitHub.