{"record":{"id":"ea12a51ca5c1edef","repo":"cube-js/cube","slug":"invalid-json-payload","errorCode":null,"errorMessage":"Invalid JSON payload","messagePattern":"Invalid JSON payload","errorType":"validation","errorClass":"CubejsHandlerError","httpStatus":400,"severity":"error","filePath":"packages/cubejs-api-gateway/src/ws/subscription-server.ts","lineNumber":55,"sourceCode":"    protected readonly contextAcceptor: ContextAcceptorFn,\n  ) {\n  }\n\n  protected resultFn(connectionId: string, messageId: string | undefined, requestId: string | undefined, logNetworkUsage: boolean = true) {\n    return async (message, { status } = { status: 200 }) => {\n      if (logNetworkUsage) {\n        this.apiGateway.log({ type: 'Outgoing network usage', service: 'api-ws', bytes: calcMessageLength(message), }, { requestId });\n      }\n\n      return this.sendMessage(connectionId, { messageId, message, status });\n    };\n  }\n\n  protected deserializeMessage(message: any): any {\n    try {\n      return JSON.parse(message);\n    } catch (e: any) {\n      throw new CubejsHandlerError(400, 'Invalid JSON payload', e.message);\n    }\n  }\n\n  protected mapZodError(error: ZodError): string {\n    return error.issues\n      .map(e => (e.path.length ? `${e.path.join('.')}: ${e.message}` : e.message))\n      .join(', ');\n  }\n\n  protected validateMessage(message: object): WsMessage {\n    if ('authorization' in message) {\n      const result = authMessageSchema.safeParse(message);\n      if (!result.success) {\n        throw new CubejsHandlerError(400, 'Invalid authorization message format', this.mapZodError(result.error));\n      }\n\n      return result.data;\n    }","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-api-gateway/src/ws/subscription-server.ts#L37-L73","documentation":"The WebSocket subscription server expects every incoming frame body to be JSON. deserializeMessage runs JSON.parse on the raw message, and on parse failure it throws CubejsHandlerError(400, 'Invalid JSON payload') carrying the underlying parser error as the reason.","triggerScenarios":"Sending a raw string over the WebSocket that is not valid JSON — unquoted text, trailing commas, single quotes, HTML, or a truncated frame; also messages that are empty or binary payloads.","commonSituations":"Hand-rolled WebSocket clients doing ws.send('load') instead of JSON.stringify({...}); curl/echo testing tools sending plain text; intermediate proxies or compression layers corrupting frames; JSON.stringify omitted in the client library glue code.","solutions":["JSON.stringify the message before sending: ws.send(JSON.stringify({ messageId: '1', ... })).","Validate the payload with JSON.parse locally to catch malformed JSON before transmitting.","Log the exact message text and the parse error (in the error reason) to find the malformed frame.","Check middleware/proxies that might truncate or transform frames."],"exampleFix":"// before\nsocket.send('load');\n// after\nsocket.send(JSON.stringify({ messageId: '1', method: 'load', query: { measures: ['Orders.count'] } }));","handlingStrategy":"validation","validationCode":"function safeWsSend(socket, payload) {\n  const text = JSON.stringify(payload);\n  JSON.parse(text); // round-trip check\n  socket.send(text);\n}","typeGuard":"function isSerializableJson(v: unknown): boolean {\n  try { JSON.parse(JSON.stringify(v)); return true; } catch { return false; }\n}","tryCatchPattern":"try {\n  await transport.sendMessage(raw);\n} catch (e) {\n  if (e.status === 400 && e.error === 'Invalid JSON payload') {\n    console.error('Sent non-JSON frame:', raw);\n  } else throw e;\n}","preventionTips":["Always JSON.stringify payloads before ws.send.","Avoid circular structures and BigInt/undefined values that break stringify semantics.","Test WS payloads with a script that validates JSON first.","Beware proxies/compression middleware that could truncate frames."],"tags":["websocket","json","validation"],"backgroundTag":"invalid-json-payload","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}