tinyhumansai/openhuman · error

[transport:cloud] HTTP

Error message

[transport:cloud] HTTP ${response.status}: ${text || response.statusText}

What it means

The cloud transport's POST to the configured rpcUrl returned a non-2xx status; the response body text (or statusText when empty) is inlined with the status code. Unlike the local coreRpcClient, this path does NO error classification — no auth_expired detection, no session event — it is a plain Error, so 401s from the cloud core will not auto-sign the user out.

Solutions

  1. Read the status from the message prefix: 401/403 → refresh the profile's bearer token; 404 → fix the rpcUrl to include the RPC path; 5xx → provider-side, retry with backoff
  2. Use testCoreRpcConnection(url, token) to validate a freshly entered URL/token before saving the profile
  3. Re-save the connection profile after cloud re-authentication so the token is current

Example fix

// before
const resp = await transport.call('core.ping', {});

// after
const probe = await testCoreRpcConnection(url, candidateToken);
if (!probe.ok) throw new Error(`profile invalid: HTTP ${probe.status}`);
setActiveCoreTransport(new CloudHttpTransport(url, candidateToken));
Defensive patterns

Strategy: validation

Validate before calling

import { testCoreRpcConnection } from '../../coreRpcClient';

async function profileReachable(url: string, token?: string): Promise<boolean> {
  try { return (await testCoreRpcConnection(url, token)).ok; } catch { return false; }
}

Type guard

function isCloudHttpError(err: unknown): err is Error & { message: string } {
  return err instanceof Error && /^\[transport:cloud\] HTTP \d{3}/.test(err.message);
}
function httpStatusOf(err: unknown): number | null {
  const m = err instanceof Error ? err.message.match(/HTTP (\d{3})/) : null;
  return m ? Number(m[1]) : null;
}

Try / catch

try {
  return await transport.call(method, params);
} catch (err) {
  const status = httpStatusOf(err);
  if (status === 401 || status === 403) { await refreshProfileToken(); return transport.call(method, params); }
  if (status === 404) throw new ConfigError('cloud RPC URL missing /rpc path');
  throw err;
}

Prevention

When it happens

Trigger: 401/403 from an expired or wrong bearerToken in the connection profile; 404 from a mis-typed cloud RPC URL; 502/503 from the cloud provider; TLS-terminating proxies rejecting the request.

Common situations: Connection profile saved with an old token after cloud re-auth; URL pointing at a REST base instead of the /rpc path; provider outage; firewall rewriting host headers.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17). Data as JSON: /api/errors/32b07ce8902062f5. Report an issue: GitHub.

Appendix: 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 7491200858)