tinyhumansai/openhuman · error · CoreRpcError
Core RPC HTTP ${response.status}: ${text || response.statusT
Error message
Core RPC HTTP ${response.status}: ${text || response.statusText} What it means
Thrown by callCoreRpc when the core's /rpc endpoint answers HTTP non-2xx: the body text is read, classifyRpcError maps it to a kind (401 -> auth_expired, which also dispatches the auth-expired event unless suppressed; 429 -> rate_limited; etc.), and a CoreRpcError carrying kind and the HTTP status is thrown. The message embeds the status plus the body text or statusText.
Source
Thrown at app/src/services/coreRpcClient.ts:745
`Core RPC ${payload.method} timed out after ${effectiveTimeoutMs}ms`,
'timeout'
);
}
throw fetchErr;
} finally {
clearTimeout(timeoutId);
}
if (!response.ok) {
const text = await response.text();
const httpMessage = `Core RPC HTTP ${response.status}: ${text || response.statusText}`;
const kind = classifyRpcError(text || response.statusText, response.status);
if (kind === 'auth_expired' && !suppressAuthExpiredEvent)
dispatchAuthExpired(
payload.method,
classifyAuthExpiredReason(text || response.statusText, response.status)
);
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');View on GitHub (pinned to a221052e0d)
Solutions
- Branch on the status: 401 -> let the auth-expired flow run (it clears/re-fetches the token; clearCoreRpcTokenCache exists for restarts); 429 -> back off; 5xx -> restart the core and retry
- Verify the rpcUrl points at the live core (GET /health and GET /schema on the same origin)
- Check core logs at the request timestamp for panics/errors behind a 500
- If it follows a core restart, ensure nothing bypasses the token-cache clearing path
Example fix
// before
await callCoreRpc({ method: 'openhuman.flows_list' });
// after
try {
await callCoreRpc({ method: 'openhuman.flows_list' });
} catch (e) {
if (e instanceof CoreRpcError && e.kind === 'auth_expired') {
await clearCoreRpcTokenCache();
return callCoreRpc({ method: 'openhuman.flows_list' }); // retry with fresh token
}
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
// Health-check the endpoint before a burst of RPCs (e.g. after a core restart)
const ok = await fetch(`${rpcBaseUrl}/health`).then(r => r.ok).catch(() => false);
if (!ok) await waitForCoreHealthy(); Type guard
import { CoreRpcError } from '../services/coreRpcClient';
function isAuthExpired(e: unknown): e is CoreRpcError & { status?: number } {
return e instanceof CoreRpcError && e.kind === 'auth_expired';
} Try / catch
try {
return await callCoreRpc(payload);
} catch (e) {
if (isAuthExpired(e)) {
clearCoreRpcTokenCache();
return callCoreRpc(payload); // re-fetch token once, then surface if it repeats
}
if (e instanceof CoreRpcError && e.status === 429) { await delay(2000); return callCoreRpc(payload); }
throw e;
} Prevention
- After any core restart, drop the cached bearer before the next RPC (restartCoreProcess shows the pattern)
- Verify rpcUrl/health when 404s appear — stale ports from previous launches are a classic cause
- Inspect err.kind and err.status rather than string-matching the message
When it happens
Trigger: 401 with a stale bearer (core restarted and minted a new token while the client cached the old one); 404 from pointing at the wrong port/path; 500/503 when the core process is crashing or its HTTP layer is wedged; any proxy in front of /rpc answering with an error status.
Common situations: Token staleness across core restarts (restartCoreProcess clears the token cache for exactly this reason); misconfigured rpcUrl (leftover port from a previous launch); core panic during a request; rate limiting through a relayed/tunneled transport.
Related errors
- RPC ${method} HTTP ${res.status}
- [transport:local] HTTP ${response.status}: ${text || respons
- RPC ${method} HTTP ${res.status}
- RPC ${method} HTTP ${res.status}
- Core RPC token unavailable in Tauri; local RPC auth cannot b
AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16).
Data as JSON: /api/errors/76943037124b6146.
Report an issue: GitHub.