tinyhumansai/openhuman · error · Error

[transport:manager] all transports failed to connect

Error message

[transport:manager] all transports failed to connect

What it means

Terminal state of raceLanAndTunnel: neither LAN (2s ping timeout) nor Tunnel answered openhuman.ping during the race window, and the Promise.any fallback wait also completed without a healthy transport. The desktop core is unreachable on every path this profile knows.

Source

Thrown at app/src/services/transport/TransportManager.ts:174

    const winner = await Promise.race([lanRace, tunnelRace]);

    if (winner) {
      // Close the losing transport.
      void winner.loser.close().catch(() => {});
      log('[transport:manager] race winner: %s', winner.transport.kind);
      return winner.transport;
    }

    // Both failed in the race window — wait for whichever succeeds.
    logErr('[transport:manager] race: both transports unhealthy; waiting…');
    const result = await Promise.any([lanRace, tunnelRace]);
    if (result) {
      void result.loser.close().catch(() => {});
      log('[transport:manager] fallback winner: %s', result.transport.kind);
      return result.transport;
    }

    throw new Error('[transport:manager] all transports failed to connect');
  }
}

// -- convenience factory ------------------------------------------------------

/**
 * Build a TransportManager from a ConnectionProfile.
 * `localRpcUrl` / `localToken` are only needed for kind="local".
 */
export function createTransportManager(
  profile: ConnectionProfile,
  opts: {
    localRpcUrl?: () => Promise<string>;
    localToken?: () => Promise<string | null>;
    backendSocketUrl?: string;
  } = {}
): TransportManager {
  const noop = () => Promise.resolve(null);

View on GitHub (pinned to a221052e0d)

Solutions

  1. Confirm the desktop app and its core are running and the machine is awake
  2. Check both paths: same Wi-Fi for LAN reachability, internet reachability for the tunnel relay (backendSocketUrl)
  3. Call manager.reset() and retry — the race can be re-run once connectivity returns
  4. If the tunnel socket reported connect_error, fix pairing/auth first (see tunnel profile errors)

Example fix

// before
const t = await manager.getTransport();

// after
let t;
try {
  t = await manager.getTransport();
} catch (e) {
  if (String(e.message).includes('all transports failed')) {
    await manager.reset();
    await sleep(2000);
    t = await manager.getTransport(); // re-race LAN vs tunnel
  } else {
    throw e;
  }
}
Defensive patterns

Strategy: retry

Validate before calling

async function backendReachable(socketUrl: string): Promise<boolean> {
  try {
    await fetch(new URL('/health', socketUrl).toString(), { method: 'HEAD' });
    return true;
  } catch {
    return false;
  }
}

Try / catch

Catch 'all transports failed', call manager.reset(), wait a short backoff, then re-attempt getTransport() up to a small bound; after the bound, surface 'core unreachable' to the user rather than looping.

Prevention

When it happens

Trigger: A kind 'tunnel' (iOS/remote) profile where the device is off the LAN (or the core is not advertising LAN) AND the tunnel relay is unreachable or fails auth — LAN ping times out and the tunnel socket errors or never responds.

Common situations: Desktop app (and its in-process core) not running; device on cellular; backend socket relay down; invalid channelId/sessionToken so tunnel connect_error fires; firewall blocking the LAN RPC port.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16). Data as JSON: /api/errors/cae4e3af1590aefd. Report an issue: GitHub.