{"record":{"id":"9660b9ebaa08aac0","repo":"CherryHQ/cherry-studio","slug":"feishu-websocket-connection-failed-error-instan","errorCode":null,"errorMessage":"Feishu WebSocket connection failed: ${error instanceof Error ? error.message : String(error)}","messagePattern":"Feishu WebSocket connection failed: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/main/ai/channels/adapters/feishu/FeishuAdapter.ts","lineNumber":433,"sourceCode":"      'im.message.receive_v1': async (data: unknown) => {\n        const event = data as FeishuMessageEvent\n        this.handleMessageEvent(event)\n      }\n    })\n\n    this.wsClient = new Lark.WSClient({\n      appId: this.appId,\n      appSecret: this.appSecret,\n      domain: larkDomain,\n      loggerLevel: Lark.LoggerLevel.error\n    })\n\n    try {\n      await this.wsClient.start({ eventDispatcher })\n    } catch (error) {\n      // Clean up so performDisconnect doesn't try to use a broken client\n      this.wsClient = null\n      throw new Error(`Feishu WebSocket connection failed: ${error instanceof Error ? error.message : String(error)}`)\n    }\n\n    this.markConnected()\n    this.log.info('Feishu bot started (WebSocket)')\n  }\n\n  /**\n   * Start the Feishu App Registration Device Flow in the background.\n   * Emits the QR URL immediately via 'qr' event and IPC, then polls\n   * asynchronously.  Does NOT block the caller.\n   */\n  private startRegistrationInBackground(signal: AbortSignal): void {\n    this.log.info('Starting Feishu app registration flow (background)', {\n      domain: this.domain\n    })\n\n    this.sendQrToRenderer('', 'pending')\n","sourceCodeStart":415,"sourceCodeEnd":451,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/src/main/ai/channels/adapters/feishu/FeishuAdapter.ts#L415-L451","documentation":"Thrown when Lark.WSClient.start() rejects during Feishu's WebSocket (long-connection) setup. The adapter wraps the SDK's start() in try/catch, nulls out wsClient on failure so later disconnect logic doesn't touch a half-built client, then re-throws with the underlying error message.","triggerScenarios":"this.wsClient.start({ eventDispatcher }) throws — appId/appSecret rejected by Feishu's handshake, wrong domain (feishu vs lark), network/DNS failure reaching the WebSocket gateway, SDK internal error, or a malformed eventDispatcher.","commonSituations":"App credentials typed for the wrong domain (feishu.cn vs larksuite.com), the app disabled or under review in the Feishu console, corporate firewall blocking the WebSocket endpoint, or an SDK upgrade that changed the start() contract.","solutions":["Confirm appId/appSecret/domain match an enabled app in the Feishu Developer Console; toggle 'Robot' capability on.","Check the embedded underlying message — 'invalid app_id or app_secret' means credentials; a connection/timeout message means network/firewall.","Ensure the host can reach the WebSocket gateway (openlark/lark domain) — test from the same network.","Pin or upgrade @larksuiteoapi/node-sdk to a version compatible with the adapter's WSClient usage."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Pre-flight credential/domain check before connect.\nfunction canStartFeishuWs(appId?: string, appSecret?: string, domain?: string): boolean {\n  return Boolean(appId && appSecret && (domain === 'feishu' || domain === 'lark'))\n}","typeGuard":"function isFeishuWsConnectError(e: unknown): e is Error {\n  return e instanceof Error && e.message.startsWith('Feishu WebSocket connection failed:')\n}","tryCatchPattern":"try {\n  await feishu.connect()\n} catch (e) {\n  if (isFeishuWsConnectError(e)) {\n    logger.error('Feishu connect failed', e)\n    notifyUser('Check Feishu appId/appSecret/domain and network')\n    return // stay disconnected; do not crash\n  }\n  throw e\n}","preventionTips":["Match appId/appSecret to the correct domain (feishu.cn vs larksuite.com).","Enable the Robot capability and publish the app in the Feishu console before connecting.","Confirm the host can reach the WebSocket gateway; test from the deployment network."],"tags":["feishu","websocket","credentials","network","lifecycle"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}