tinyhumansai/openhuman · error
[transport:cloud] timed out after ms
Error message
[transport:cloud] ${method} timed out after ${this.timeoutMs}ms What it means
CloudHttpTransport.call aborts its fetch via AbortController after this.timeoutMs (constructor arg, default 30_000) and reports it as this timeout error. Because the caller-provided opts.signal is also wired to abort the same controller, ANY abort — the caller's own cancellation or the timeout — is reported through this branch as a 'timed out' message; there is no separate cancellation error. The transport is installed by TransportManager for user-configured cloud cores via setActiveCoreTransport, after which every callCoreRpc routes through it.
Solutions
- Raise the transport's timeoutMs at construction for known-heavy methods (it is a constructor parameter, not per-call)
- Distinguish caller cancellation from real timeout before reporting: check your own signal's aborted state, since the transport folds both into one message
- Filter these in Sentry/telemetry by the '[transport:cloud]' prefix or switch on the method name
- Verify cloud core health if timeouts are persistent rather than network-driven
Example fix
// before const t = new CloudHttpTransport(url, token); // after const t = new CloudHttpTransport(url, token, 60_000); // explicit budget for slow cloud handlers
Defensive patterns
Strategy: retry
Type guard
function isCloudTransportTimeout(err: unknown): boolean {
return err instanceof Error && err.message.startsWith('[transport:cloud]') && err.message.includes('timed out');
} Try / catch
const mySignal = new AbortController().signal;
try {
return await transport.call(method, params, { signal: mySignal });
} catch (err) {
if (isCloudTransportTimeout(err) && !mySignal.aborted && isIdempotent(method)) {
return await transport.call(method, params); // true timeout → one retry
}
if (mySignal.aborted) return cancelled(); // caller cancel mislabeled as timeout
throw err;
} Prevention
- Size the transport's timeoutMs for the slowest method you call — it is per-transport, not per-call
- Check your own signal before classifying: caller aborts are reported as timeouts here
- Filter '[transport:cloud]' timeout messages in telemetry to cut unmount-abort noise
When it happens
Trigger: Any callCoreRpc through an active cloud transport whose round-trip exceeds timeoutMs (default 30s): slow cloud RPC, high-latency link, or a hung cloud core; alternatively a caller aborting its opts.signal, which is misreported with the timeout message.
Common situations: Mobile/remote profile on a poor connection with the default 30s budget; a cloud core executing a heavy handler; component unmounts aborting in-flight calls and logs polluting Sentry with pseudo-timeouts; constructing the transport with an undersized timeoutMs.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- [transport:lan] timed out after ms
- Cloud RPC returned an error
- Core RPC timed out after ms
- [transport:cloud] HTTP
- [transport:cloud] response missing result
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/197bfc1c99aa09bf.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/services/transport/CloudHttpTransport.ts:66
if (this.bearerToken) {
headers.Authorization = `Bearer ${this.bearerToken}`;
}
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
opts?.signal?.addEventListener('abort', () => controller.abort());
let response: Response;
try {
response = await fetch(this.rpcUrl, {
method: 'POST',
headers,
body: JSON.stringify(payload),
signal: controller.signal,
});
} catch (err) {
if (controller.signal.aborted) {
throw new Error(`[transport:cloud] ${method} timed out after ${this.timeoutMs}ms`);
}
throw err;
} finally {
clearTimeout(timeoutId);
}
if (!response.ok) {
const text = await response.text();
throw new Error(`[transport:cloud] HTTP ${response.status}: ${text || response.statusText}`);
}
const json = (await response.json()) as JsonRpcResponse<T>;
if (json.error) {
logErr('[transport:cloud] ← %s error: %s', method, json.error.message);
throw new Error(json.error.message ?? 'Cloud RPC returned an error');
}
if (!Object.prototype.hasOwnProperty.call(json, 'result')) {View on GitHub (pinned to 7491200858)