{"record":{"id":"8e13d3e94c2b8423","repo":"hcengineering/platform","slug":"platform-status-badrequest","errorCode":"platform.status.BadRequest","errorMessage":"BadRequest","messagePattern":"BadRequest","errorType":"error_code","errorClass":"PlatformError","httpStatus":400,"severity":"warning","filePath":"foundations/core/packages/rpc/src/rpc.ts","lineNumber":202,"sourceCode":"   * @returns\n   */\n  readResponse<D>(response: any, binary: boolean): Response<D> {\n    const data = this.protoDeserialize(response, binary)\n    if (data.result !== undefined) {\n      data.result = rpcJSONReceiver('result', data.result)\n    }\n    return data\n  }\n\n  /**\n   * @public\n   * @param request -\n   * @returns\n   */\n  readRequest<P extends any[]>(request: any, binary: boolean): Request<P> {\n    const result: Request<P> = this.protoDeserialize(request, binary)\n    if (typeof result.method !== 'string') {\n      throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))\n    }\n    return result\n  }\n}\n\n/**\n * @public\n * @param status -\n * @param id -\n * @returns\n */\nexport function fromStatus (status: Status, id?: ReqId): Response<any> {\n  return { id, error: status }\n}\n","sourceCodeStart":184,"sourceCodeEnd":217,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/foundations/core/packages/rpc/src/rpc.ts#L184-L217","documentation":"readRequest deserializes an incoming RPC payload with protoDeserialize (JSON or msgpack) and then validates that the decoded object has a string `method` field. If the payload decodes to something without a string method — garbage bytes, wrong encoding, or a non-RPC body — the server rejects it with a PlatformError carrying platform.status.BadRequest. It is a protocol-level guard against malformed client requests.","triggerScenarios":"Server calls readRequest (via request/cs) on a payload where protoDeserialize yields an object whose `method` is not a string: non-RPC data sent to the RPC endpoint, JSON payload decoded when the client actually sent msgpack (binary flag mismatch), truncated/corrupted frames, or a raw HTTP client posting arbitrary JSON without a `method` field.","commonSituations":"Client and server built from different package versions with different serialization defaults (JSON vs msgpack); a proxy/worker re-encoding the body; curl/Postman tests hitting the RPC endpoint with plain JSON like {\"id\":1} but no `method`; a WebSocket client speaking the wrong protocol revision.","solutions":["Log the raw payload and the binary flag on the server just before readRequest to see what actually arrived.","Verify the client serializes with the same format/protocol version as the server expects (binary vs JSON) and that both use the same @hcengineering/rpc version.","If testing manually, send a full RPC Request object, e.g. {id:1, method:'methodName', params:[...]}.","Check any intermediate proxy/gateway is not stripping or re-encoding the request body."],"exampleFix":"// before: hand-crafted payload posted to the RPC endpoint\nfetch(rpcUrl, { method: 'POST', body: JSON.stringify({ method: 'hello' }) }) // missing id/params, or wrong encoding\n\n// after: use the client-side serializer so the shape matches\nconst payload = RPC.serialize({ id: 1, method: 'hello', params: [] }, binary)\nawait send(payload)","handlingStrategy":"try-catch","validationCode":"// client-side: confirm the payload decodes to a Request with a string method before sending\nfunction isRpcRequest (p: unknown): boolean {\n  return typeof p === 'object' && p !== null && typeof (p as any).method === 'string'\n}\nif (!isRpcRequest(myPayload)) throw new TypeError('Not a valid RPC request payload')","typeGuard":"function isRequest<P extends any[]> (v: unknown): v is { id: string, method: string, params: P } {\n  return typeof v === 'object' && v !== null && typeof (v as any).method === 'string' && Array.isArray((v as any).params)\n}","tryCatchPattern":"try {\n  const req = rpc.readRequest(payload, binary)\n  // handle\n} catch (err) {\n  if (err instanceof PlatformError && err.status.code === platform.status.BadRequest) {\n    // log raw payload + binary flag, respond 400\n  } else throw err\n}","preventionTips":["Always build requests through the library's serialize() path, never hand-rolled JSON.","Keep @hcengineering/rpc versions identical on client and server.","Verify the binary flag matches the transport framing on both ends.","Add a debug log of the raw payload when BadRequest occurs."],"tags":["rpc","serialization","protocol","bad-request"],"backgroundTag":"rpc-request-deserialization-failed","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}