tinyhumansai/openhuman · error
[transport:local] ${method} timed out after ${this.timeoutMs
Error message
[transport:local] ${method} timed out after ${this.timeoutMs}ms What it means
Local transport timeout: the desktop renderer's `fetch` to the in-process core at `127.0.0.1:<port>/rpc` rejected with the shared controller aborted. Sources: the internal `setTimeout` (default 30s) or the caller's own `opts.signal` — the `controller.signal.aborted` check conflates them, so deliberate cancellation is also reported as a timeout. Since this is loopback, network latency is not the issue: the core process is busy, hung, restarting, or the method genuinely needs more than 30s.
Source
Thrown at app/src/services/transport/LocalTransport.ts:68
}
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
// Merge caller signal with timeout signal.
opts?.signal?.addEventListener('abort', () => controller.abort());
let response: Response;
try {
response = await fetch(rpcUrl, {
method: 'POST',
headers,
body: JSON.stringify(payload),
signal: controller.signal,
});
} catch (err) {
if (controller.signal.aborted) {
throw new Error(`[transport:local] ${method} timed out after ${this.timeoutMs}ms`);
}
throw err;
} finally {
clearTimeout(timeoutId);
}
if (!response.ok) {
const text = await response.text();
throw new Error(`[transport:local] HTTP ${response.status}: ${text || response.statusText}`);
}
const json = (await response.json()) as JsonRpcResponse<T>;
if (json.error) {
logErr('[transport:local] ← %s error: %s', method, json.error.message);
throw new Error(json.error.message ?? 'Core RPC returned an error');
}
if (!Object.prototype.hasOwnProperty.call(json, 'result')) {View on GitHub (pinned to a221052e0d)
Solutions
- Check the core log for the method's duration — if it completes in >30s, raise the transport's `timeoutMs` for that call or make the method async/ streamed core-side
- Confirm the core process is healthy (daemonHealthService / `openhuman ping`) and not restart-looping
- If you pass `opts.signal`, verify whether your own cancellation caused the abort before treating it as a hang
- Retry idempotent calls once the core is idle
Example fix
// before
new LocalTransport(getCoreRpcUrl, getCoreRpcToken) // 30s default
await transport.call('openhuman.memory_full_sync', {});
// after
new LocalTransport(getCoreRpcUrl, getCoreRpcToken, 120_000)
await transport.call('openhuman.memory_full_sync', {}); Defensive patterns
Strategy: retry
Validate before calling
import { daemonHealthService } from '../services/daemonHealthService';
if (!(await daemonHealthService.isHealthy())) {
await restartCoreProcess(); // core down/restart-looping — retrying the call is pointless
} Type guard
function isLocalTimeout(e: unknown): boolean {
return e instanceof Error && e.message.startsWith('[transport:local]') && e.message.includes('timed out');
} Try / catch
for (let a = 1; a <= 2; a++) {
try { return await local.call(m, p); }
catch (e) {
if (!isLocalTimeout(e) || a === 2 || opts?.signal?.aborted) throw e;
await sleep(2 ** a * 500);
}
} Prevention
- Give known-slow methods (sync, backfill, generation) a transport with a raised timeoutMs
- Check core health before retrying — a hung/restart-looping core will time out every time
- If you pass opts.signal, note that your own abort produces the same 'timed out' message; check opts.signal.aborted in the handler
When it happens
Trigger: Long-running RPC methods (memory sync, full-tool runs, backfills) exceeding 30s; the core blocked on a synchronous operation or deadlock; core mid-restart (CoreProcessHandle respawn) when the request lands; caller aborting via `opts.signal` and the message misattributing it.
Common situations: First-run heavy ingestion on a big workspace; a core panic loop during development; devtools network throttling accidentally applied to localhost; a new method added without considering the 30s ceiling.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- [transport:cloud] ${method} timed out after ${this.timeoutMs
- [transport:lan] ${method} timed out after ${this.timeoutMs}m
- Request timed out. Please try again.
- Core RPC ${payload.method} timed out after ${effectiveTimeou
- Core RPC returned an error
AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16).
Data as JSON: /api/errors/5f96e4bb297fb5e4.
Report an issue: GitHub.