{"record":{"id":"fade56031214fcf0","repo":"tinyhumansai/openhuman","slug":"transport-manager-unknown-profile-kind-kind","errorCode":null,"errorMessage":"[transport:manager] unknown profile kind: ${kind}","messagePattern":"\\[transport:manager\\] unknown profile kind: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"app/src/services/transport/TransportManager.ts","lineNumber":101,"sourceCode":"      log('[transport:manager] → CloudHttpTransport rpcUrl=%s', rpcUrl);\n      return t;\n    }\n\n    if (kind === 'lan') {\n      const { rpcUrl } = this.profile;\n      if (!rpcUrl) {\n        throw new Error('[transport:manager] lan profile missing rpcUrl');\n      }\n      const t = new LanHttpTransport(rpcUrl);\n      log('[transport:manager] → LanHttpTransport rpcUrl=%s', rpcUrl);\n      return t;\n    }\n\n    if (kind === 'tunnel') {\n      return this.raceLanAndTunnel();\n    }\n\n    throw new Error(`[transport:manager] unknown profile kind: ${kind}`);\n  }\n\n  /**\n   * Race LAN (with 2 s timeout) against Tunnel.\n   * Whichever responds to `openhuman.ping` first wins.\n   * If LAN wins but later fails, caller should call reset() to re-race.\n   */\n  private async raceLanAndTunnel(): Promise<CoreTransport> {\n    const { rpcUrl, channelId, corePubkey, sessionToken, pairingToken, devicePrivkey } =\n      this.profile;\n\n    if (!channelId || !corePubkey) {\n      throw new Error('[transport:manager] tunnel profile missing channelId or corePubkey');\n    }\n\n    const tunnelToken = sessionToken ?? pairingToken;\n    if (!tunnelToken) {\n      throw new Error('[transport:manager] tunnel profile missing sessionToken or pairingToken');","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/app/src/services/transport/TransportManager.ts#L83-L119","documentation":"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.","triggerScenarios":"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.","commonSituations":"App rollback after a newer release added a transport kind; profile persisted by a different client version; fixtures written against a future schema.","solutions":["Inspect the persisted profile JSON and correct kind to one of local|cloud|lan|tunnel","If a new kind was added upstream, ship the matching consumer in the same release or pin versions together","Treat unknown kinds at load time as corrupt: delete and re-pair rather than crashing at first RPC"],"exampleFix":"// before\nconst tm = createTransportManager(profile, opts);\n\n// after\nconst KNOWN_KINDS = new Set(['local', 'cloud', 'lan', 'tunnel']);\nif (!KNOWN_KINDS.has(profile.kind)) {\n  await discardProfileAndRePair(profile.id);\n} else {\n  const tm = createTransportManager(profile, opts);\n}","handlingStrategy":"type-guard","validationCode":"const KNOWN_KINDS = new Set(['local', 'cloud', 'lan', 'tunnel']);\nif (!KNOWN_KINDS.has(profile.kind)) {\n  await discardProfileAndRePair(profile.id);\n}","typeGuard":"type KnownKind = 'local' | 'cloud' | 'lan' | 'tunnel';\nfunction isKnownKind(k: unknown): k is KnownKind {\n  return typeof k === 'string' && ['local', 'cloud', 'lan', 'tunnel'].includes(k);\n}","tryCatchPattern":null,"preventionTips":["Persist a schema version alongside profiles and migrate on load","Ship producer and consumer of any new profile kind in the same release","Treat unknown kinds as corrupt profiles: delete and re-pair instead of crashing"],"tags":["transport","connection-profile","schema","version-skew"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}