{"record":{"id":"59c1349320b1763d","repo":"unionlabs/union","slug":"malformed-response","errorCode":null,"errorMessage":"Malformed response","messagePattern":"Malformed response","errorType":"exception","errorClass":"RpcStatusError","httpStatus":null,"severity":"warning","filePath":"app2/src/routes/nodes/+page.svelte","lineNumber":82,"sourceCode":"      if (type === \"cosmos\") {\n        const { result: res, duration } = await withTiming(async () =>\n          fetch(url, {\n            method: \"POST\",\n            headers: { \"Content-Type\": \"application/json\" },\n            body: JSON.stringify({\n              jsonrpc: \"2.0\",\n              id: 1,\n              method: \"status\",\n              params: [],\n            }),\n          })\n        )\n        if (!res.ok) {\n          throw new RpcStatusError(\"cosmos\", url, `HTTP ${res.status} - ${res.statusText}`)\n        }\n        const data = await res.json()\n        if (!(data?.result?.sync_info && data?.result?.node_info)) {\n          throw new RpcStatusError(\"cosmos\", url, \"Malformed response\", data)\n        }\n        return {\n          url,\n          type: \"cosmos\",\n          responseTimeMs: duration,\n          status: {\n            kind: \"cosmos\",\n            latestBlockHeight: Number(data.result.sync_info.latest_block_height),\n            catchingUp: data.result.sync_info.catching_up,\n            moniker: data.result.node_info.moniker,\n            network: data.result.node_info.network,\n          },\n        }\n      }\n      if (type === \"evm\") {\n        const { result: res, duration } = await withTiming(async () =>\n          fetch(url, {\n            method: \"POST\",","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/unionlabs/union/blob/031785bb6dc6b957c624e62bc64c184409c97d7b/app2/src/routes/nodes/+page.svelte#L64-L100","documentation":"RpcStatusError thrown after a successful HTTP 200 from a Cosmos RPC probe: the JSON-RPC response parsed fine, but data.result.sync_info and/or data.result.node_info are missing, so the payload is not shaped like a CometBFT \"status\" result. The offending payload is attached to the error for inspection.","triggerScenarios":"POSTing {method:\"status\"} to an endpoint that returns 200 with a different body shape: an EVM JSON-RPC node (returns {result:\"0x...\"}), a JSON-RPC error object {error:{...}}, a REST/LCD gateway, or an HTML/JSON welcome page from a proxy.","commonSituations":"Mixing up node types when adding URLs to the status checker (an Ethereum RPC in the Cosmos list); endpoints fronted by proxies that rewrite responses; JSON-RPC errors (rate limit, invalid method) that still use HTTP 200.","solutions":["Check the attached data payload: if it has an error field, fix the underlying JSON-RPC problem (method/rate limit/auth)","Move the URL to the correct list (EVM endpoints belong to the eth_blockNumber probe)","Use a real CometBFT RPC endpoint (port 26657) that supports the \"status\" method"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"const data = await res.json()\nconst isCosmosStatusResult = (d: unknown): d is { result: { sync_info: unknown; node_info: unknown } } =>\n  typeof d === \"object\" && d !== null &&\n  \"result\" in d &&\n  typeof (d as any).result === \"object\" &&\n  (d as any).result !== null &&\n  \"sync_info\" in (d as any).result &&\n  \"node_info\" in (d as any).result\n\nif (!isCosmosStatusResult(data)) {\n  // classify: EVM node vs JSON-RPC error, then mark endpoint misconfigured\n}","typeGuard":"const isCosmosStatusPayload = (d: any): d is { result: { sync_info: { latest_block_height: string; catching_up: boolean }; node_info: { moniker: string; network: string } } } =>\n  Boolean(d?.result?.sync_info && d?.result?.node_info)","tryCatchPattern":"try {\n  status = await checkCosmos(url)\n} catch (error) {\n  if (error instanceof RpcStatusError && error.message === \"Malformed response\") {\n    // inspect error.data: presence of .error means RPC-level failure; a hex .result means it is an EVM endpoint\n  }\n  throw error\n}","preventionTips":["Validate response shape (result.sync_info + node_info) before parsing fields","Keep Cosmos and EVM endpoint lists separate and type-tag them","Check the JSON-RPC error field whenever HTTP 200 still yields no result"],"tags":["cosmos","rpc","json-rpc","validation"],"backgroundTag":null,"analyzedSha":"031785bb6dc6b957c624e62bc64c184409c97d7b","analyzedAt":"2026-08-16T06:24:09.996Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}