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

  1. Restart the connection/driver to resynchronize the message protocol
  2. Check for Cube Store restarts or multiple clients sharing one connection
  3. Align Cube Store and driver versions
  4. 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

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


AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02). Data as JSON: /api/errors/9c325cf02cba7cba. Report an issue: GitHub.