{"record":{"id":"186432a72def64be","repo":"tinyhumansai/openhuman","slug":"core-rpc-response-missing-result","errorCode":null,"errorMessage":"Core RPC response missing result","messagePattern":"Core RPC response missing result","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/src/services/coreRpcClient.ts","lineNumber":763,"sourceCode":"      throw new CoreRpcError(httpMessage, kind, response.status);\n    }\n\n    const json = (await response.json()) as JsonRpcResponse<T>;\n\n    if (json.error) {\n      coreRpcError('HTTP error response', {\n        id: payload.id,\n        method: payload.method,\n        error: json.error,\n      });\n      const rawMessage = json.error.message || 'Core RPC returned an error';\n      const kind = classifyRpcError(rawMessage, undefined, json.error.data);\n      if (kind === 'auth_expired' && !suppressAuthExpiredEvent)\n        dispatchAuthExpired(payload.method, classifyAuthExpiredReason(rawMessage, undefined));\n      throw new CoreRpcError(rawMessage, kind, undefined, json.error.data);\n    }\n    if (!Object.prototype.hasOwnProperty.call(json, 'result')) {\n      throw new Error('Core RPC response missing result');\n    }\n\n    coreRpcLog('HTTP response', { id: payload.id, method: payload.method });\n    return json.result as T;\n  } catch (err) {\n    coreRpcError('Core RPC call failed', sanitizeError(err));\n    if (err instanceof CoreRpcError) throw err;\n    const message = coreRpcErrorMessage(err);\n    throw new CoreRpcError(message, classifyRpcError(message));\n  }\n}\n","sourceCodeStart":745,"sourceCodeEnd":775,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/app/src/services/coreRpcClient.ts#L745-L775","documentation":"Thrown when a call to the local core returns HTTP 200 with valid JSON that contains neither an `error` field nor a `result` field. Per JSON-RPC 2.0, a response object must have exactly one of `result` or `error`, so this is a malformed/foreign response — the client deliberately refuses to treat `undefined` as a result. It fires after the `json.error` branch, so the server really did answer 'success-shaped' but with no payload.","triggerScenarios":"The RPC URL resolves to an endpoint that returns 200 + JSON without JSON-RPC shape: a health endpoint, a mock/stub server replying `{}`, or a proxy that rewrites the body. Also a core bug or middleware that emits `{jsonrpc, id}` with the result dropped during serialization.","commonSituations":"`rpcUrl` pointing at `/health` or the wrong port instead of `http://127.0.0.1:<port>/rpc`; running against a hand-rolled test stub that replies `{ok:true}`; an intermediate dev proxy (Vite middleware, service worker) stripping the body; version skew after the wire shape changed.","solutions":["Verify the resolved RPC URL — log `await getCoreRpcUrl()` and confirm it ends in `/rpc` on the core port from `core_rpc_url`","curl the endpoint directly with a minimal JSON-RPC frame (`{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"openhuman.ping\",\"params\":{}}`) and inspect the raw body","If using a mock/stub server, make it reply with `{jsonrpc:'2.0', id, result:{}}` for every frame","Check for a proxy or interceptor between renderer and core and bypass it for `/rpc`"],"exampleFix":"// before (stub server replying empty)\napp.post('/rpc', (_req, res) => res.json({}));\n\n// after\napp.post('/rpc', (req, res) =>\n  res.json({ jsonrpc: '2.0', id: req.body.id, result: { pong: true } })\n);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { const r = await callCoreRpc<T>(m, p); }\ncatch (e) {\n  if (e instanceof Error && e.message === 'Core RPC response missing result') {\n    logRpcShapeIssue(m); // endpoint config problem, not a business failure\n    return undefined;\n  }\n  throw e;\n}","preventionTips":["Assert the RPC URL ends with /rpc on the core port before first use","Smoke-test every environment once with openhuman.ping — shape errors surface immediately","Make mock/stub servers reply with full JSON-RPC frames ({jsonrpc, id, result})"],"tags":["json-rpc","core-rpc","validation","mocking"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}