tinyhumansai/openhuman · error
Core RPC response missing result
Error message
Core RPC response missing result
What it means
The response parsed as JSON and carried no json.error, but also had no own 'result' property — violating the JSON-RPC 2.0 response shape (exactly one of result/error must be present). This is checked with Object.prototype.hasOwnProperty, so a result of undefined or null still passes; only a structurally missing key triggers it.
Solutions
- Verify the RPC URL resolves to the core's POST /rpc endpoint (use testCoreRpcConnection / core.ping) — an alien 200 JSON envelope is the usual cause
- Reproduce with curl against the same URL+token and inspect the raw body shape
- Fix test/mocks to wrap responses as {jsonrpc:'2.0', id, result: ...}
- If a proxy sits in front, bypass it or configure it to pass the core response through untouched
Example fix
// before (mock returning wrong envelope)
fetchMock.mockResolvedValue({ ok: true, body: { ok: true } });
// after
fetchMock.mockResolvedValue({ ok: true, body: { jsonrpc: '2.0', id: 1, result: { ok: true } } }); Defensive patterns
Strategy: type-guard
Validate before calling
function isJsonRpcResultEnvelope(body: unknown): body is { result: unknown } {
return !!body && typeof body === 'object' && 'result' in (body as object);
} Type guard
function hasResultProp(json: unknown): boolean {
return Object.prototype.hasOwnProperty.call(json ?? {}, 'result');
} Try / catch
try {
return await callCoreRpc({ method, params });
} catch (err) {
if (err instanceof Error && err.message === 'Core RPC response missing result') {
// transport reached something that is not the core's /rpc — check URL/proxy
throw new ConfigError(`RPC URL does not serve JSON-RPC: ${await getCoreRpcUrl()}`);
}
throw err;
} Prevention
- Probe with core.ping (testCoreRpcConnection) whenever the RPC URL is user-configured
- In tests, wrap mocked bodies as {jsonrpc:'2.0', id, result} — never return payload objects bare
- Keep proxies/middleware from rewriting /rpc bodies
When it happens
Trigger: A proxy, middleware, or misrouted endpoint answering with a different JSON envelope ({success,data}, empty object, or a status object) on a 200; a core build whose handler serializes RpcOutcome without unwrapping to a result field; response body rewritten by a service worker or intercepting layer.
Common situations: Pointing the RPC URL at a backend REST route instead of the core /rpc route; a reverse proxy health-check response; version skew where an old core returned a different envelope; test mocks returning {ok:true} directly as the whole body instead of {jsonrpc,result:{ok:true}}.
Related errors
- Core RPC returned an error
- [transport:cloud] response missing result
- At least one of --expression, --tz, --command, or --name…
- Cloud RPC returned an error
- Core rejected the agent_meetings_join request.
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/186432a72def64be.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/services/coreRpcClient.ts:763
throw new CoreRpcError(httpMessage, kind, response.status);
}
const json = (await response.json()) as JsonRpcResponse<T>;
if (json.error) {
coreRpcError('HTTP error response', {
id: payload.id,
method: payload.method,
error: json.error,
});
const rawMessage = json.error.message || 'Core RPC returned an error';
const kind = classifyRpcError(rawMessage, undefined, json.error.data);
if (kind === 'auth_expired' && !suppressAuthExpiredEvent)
dispatchAuthExpired(payload.method, classifyAuthExpiredReason(rawMessage, undefined));
throw new CoreRpcError(rawMessage, kind, undefined, json.error.data);
}
if (!Object.prototype.hasOwnProperty.call(json, 'result')) {
throw new Error('Core RPC response missing result');
}
coreRpcLog('HTTP response', { id: payload.id, method: payload.method });
return json.result as T;
} catch (err) {
coreRpcError('Core RPC call failed', sanitizeError(err));
if (err instanceof CoreRpcError) throw err;
const message = coreRpcErrorMessage(err);
throw new CoreRpcError(message, classifyRpcError(message));
}
}
View on GitHub (pinned to 7491200858)