tinyhumansai/openhuman · error
[transport:cloud] HTTP ${response.status}: ${text || respons
Error message
[transport:cloud] HTTP ${response.status}: ${text || response.statusText} What it means
Thrown when the cloud core answers with a non-2xx HTTP status: the transport reads the body text and embeds both status and body (falling back to `statusText` when the body is empty). This is transport-level failure before JSON-RPC parsing — the message tells you exactly what the HTTP layer saw.
Source
Thrown at app/src/services/transport/CloudHttpTransport.ts:75
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')) {
throw new Error('[transport:cloud] response missing result');
}
log('[transport:cloud] ← %s id=%d ok', method, id);
return json.result as T;
}
async *stream<T>(
method: string,View on GitHub (pinned to a221052e0d)
Solutions
- Read the embedded status: 401/403 → refresh or re-supply the bearer token in the connection profile; 404 → fix rpcUrl; 5xx → retry later
- Confirm the rpcUrl includes the full JSON-RPC path, not just the host
- For 413, shrink the request (batch or paginate params)
- Check the provider status page if 5xx persists across methods
Example fix
// before
const t = new CloudHttpTransport(url, null);
// after — fail fast on config, not mid-call
if (!profile.bearerToken) throw new Error('Connection profile is missing its cloud token');
const t = new CloudHttpTransport(url, profile.bearerToken); Defensive patterns
Strategy: try-catch
Validate before calling
const parsed = new URL(rpcUrl);
if (!/^https?:$/.test(parsed.protocol)) throw new Error('rpcUrl must be http(s)');
if (requireAuth && !bearerToken) throw new Error('cloud profile missing token'); Type guard
function isCloudHttpError(e: unknown): e is Error & { status?: number } {
if (!(e instanceof Error) || !e.message.startsWith('[transport:cloud] HTTP ')) return false;
return true;
} Try / catch
try { await transport.call(m, p); }
catch (e) {
const m_ = e instanceof Error ? e.message : '';
if (m_.startsWith('[transport:cloud] HTTP 401')) return reAuth();
if (/HTTP 5\d\d/.test(m_)) return retryLater();
throw e;
} Prevention
- Validate the connection profile's URL and token at connect time, not on first call
- Parse the embedded status out of the message to branch (401 vs 5xx) instead of showing raw text
- Keep bearer tokens fresh — rotate before expiry, since no header is sent when the token is null
When it happens
Trigger: 401 when `bearerToken` is null (the header is simply omitted) or the token from the connection profile is expired/revoked; 404 for a wrong `rpcUrl` path; 405 when hitting a GET-only endpoint; 502/503/504 from the cloud gateway during deploys or outages; 413 for oversized payloads.
Common situations: Connection profile created without a token against an auth-required core; stale token after cloud session rotation; typo'd or version-changed rpcUrl; cloud provider incident; reverse-proxy body limits.
Related errors
- [transport:cloud] ${method} timed out after ${this.timeoutMs
- [transport:lan] HTTP ${response.status}: ${text || response.
- [transport:local] HTTP ${response.status}: ${text || respons
- Failed to send magic link (${response.status})
- HTTP error! status: ${response.status}
AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16).
Data as JSON: /api/errors/32b07ce8902062f5.
Report an issue: GitHub.