tinyhumansai/openhuman · error · Error

[transport:manager] unknown profile kind: ${kind}

Error message

[transport:manager] unknown profile kind: ${kind}

What it means

buildTransport switches on profile.kind and only knows 'local' | 'cloud' | 'lan' | 'tunnel'; any other string falls through to this error. It signals a schema/version mismatch between the code that produced the profile and this consumer — the profile data is valid for someone, just not this build.

Source

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

      log('[transport:manager] → CloudHttpTransport rpcUrl=%s', rpcUrl);
      return t;
    }

    if (kind === 'lan') {
      const { rpcUrl } = this.profile;
      if (!rpcUrl) {
        throw new Error('[transport:manager] lan profile missing rpcUrl');
      }
      const t = new LanHttpTransport(rpcUrl);
      log('[transport:manager] → LanHttpTransport rpcUrl=%s', rpcUrl);
      return t;
    }

    if (kind === 'tunnel') {
      return this.raceLanAndTunnel();
    }

    throw new Error(`[transport:manager] unknown profile kind: ${kind}`);
  }

  /**
   * Race LAN (with 2 s timeout) against Tunnel.
   * Whichever responds to `openhuman.ping` first wins.
   * If LAN wins but later fails, caller should call reset() to re-race.
   */
  private async raceLanAndTunnel(): Promise<CoreTransport> {
    const { rpcUrl, channelId, corePubkey, sessionToken, pairingToken, devicePrivkey } =
      this.profile;

    if (!channelId || !corePubkey) {
      throw new Error('[transport:manager] tunnel profile missing channelId or corePubkey');
    }

    const tunnelToken = sessionToken ?? pairingToken;
    if (!tunnelToken) {
      throw new Error('[transport:manager] tunnel profile missing sessionToken or pairingToken');

View on GitHub (pinned to a221052e0d)

Solutions

  1. Inspect the persisted profile JSON and correct kind to one of local|cloud|lan|tunnel
  2. If a new kind was added upstream, ship the matching consumer in the same release or pin versions together
  3. Treat unknown kinds at load time as corrupt: delete and re-pair rather than crashing at first RPC

Example fix

// before
const tm = createTransportManager(profile, opts);

// after
const KNOWN_KINDS = new Set(['local', 'cloud', 'lan', 'tunnel']);
if (!KNOWN_KINDS.has(profile.kind)) {
  await discardProfileAndRePair(profile.id);
} else {
  const tm = createTransportManager(profile, opts);
}
Defensive patterns

Strategy: type-guard

Validate before calling

const KNOWN_KINDS = new Set(['local', 'cloud', 'lan', 'tunnel']);
if (!KNOWN_KINDS.has(profile.kind)) {
  await discardProfileAndRePair(profile.id);
}

Type guard

type KnownKind = 'local' | 'cloud' | 'lan' | 'tunnel';
function isKnownKind(k: unknown): k is KnownKind {
  return typeof k === 'string' && ['local', 'cloud', 'lan', 'tunnel'].includes(k);
}

Prevention

When it happens

Trigger: profile.kind is e.g. 'remote', 'ws', a typo, or a kind introduced by a newer build — downgraded app reading a profile written upstream; hand-authored profile JSON; enum renamed during a refactor.

Common situations: App rollback after a newer release added a transport kind; profile persisted by a different client version; fixtures written against a future schema.

Related errors


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