April 21, 2026 • バージョン: 2026.2.26

[FeishuチャンネルのWebSocketモードでclient.onが関数ではないエラー] - Feishu Channel WebSocket Mode: client.on is not a function

OpenClaw 2026.2.26において、WebSocketクライアントの初期化に失敗したことにより、Feishuチャンネルが起動時に'client.on is not a function'でクラッシュします。

🔍 症状

主なエラーの発生状況

Feishuチャンネルが初期化時に即座に終了し、以下のTypeErrorが発生します:

[default] channel exited: client.on is not a function

実行コンテキスト

エラーは、WebSocketハンドシェイクフェーズ中に発生します。ログシーケンスから確認できます:

{"subsystem":"gateway/channels/feishu","1":"starting feishu[default] (mode: websocket)"}
{"subsystem":"gateway/channels/feishu","1":"feishu[${accountId}]: bot open_id resolved: ${botOpenId ?? \"unknown\"}"}
{"subsystem":"gateway/channels/feishu","1":"[default] channel exited: client.on is not a function"}
{"subsystem":"gateway/channels/feishu","1":"[default] auto-restart attempt 3/10 in 20s"}

診断の観察結果

  • Bot ID解決は成功: `open_id`ログエントリにより、API認証(appId/appSecret)が機能していることが確認されます。
  • アウトバウンド通信に影響なし: Feishuチャンネルを介したメッセージ送信は正常に機能します。
  • インバウンド処理が破綻: Feishuユーザーからの受信メッセージが処理されません。
  • リトライループ開始: チャンネルが指数関数的バックオフを伴う継続的な再起動サイクルに入ります。

CLI検査コマンド

この状態を手動で診断するには:

# Check OpenClaw version
openclaw --version
# Expected: OpenClaw v2026.2.26

# Verify Feishu channel configuration
openclaw config get channels.feishu

# View real-time logs (if logging level permits)
openclaw logs --follow --filter feishu

🧠 原因

アーキテクチャ上の障害ポイント

エラーclient.on is not a functionは、FeishuチャンネルアダプタにおけるWebSocketクライアントの不適切な初期化に起因します。コードは、EventEmitter互換のAPIを欠いたクライアントオブジェクトにイベントリスナーの添付を試みています。

障害シーケンスの分析

  1. チャンネル初期化: OpenClawがWebSocketモードでFeishuチャンネルアダプタをインスタンス化します。
  2. クライアント作成: アダプタがWebSocketライブラリのコンストラクタを呼び出します。
  3. APIの不一致: コードは`.on(event, handler)`メソッドを持つ標準的なWebSocketオブジェクトを期待しますが、以下のいずれかが返されます:
    • 生のHTTPクライアントレスポンスオブジェクト
    • 不適切にラップされたWebSocket接続
    • 互換性のないAPI поверхностиを持つWebSocketShimインスタンス
  4. イベントバインディングの失敗: `client.on('message', handler)`の呼び出しがTypeError: client.on is not a functionをスローします。
  5. 正常な終了: チャンネルがエラーをキャッチし、報告されたメッセージで終了します。

問題のあるコードパス

問題のある初期化は、おそらく以下のようなパターンです:

// Hypothetical incorrect implementation (simplified)
const WebSocket = require('ws');

class FeishuChannel {
  async connect(config) {
    const wsUrl = await this.obtainWebSocketEndpoint(config);
    
    // BUG: Using WebSocket constructor directly instead of proper connection
    const client = new WebSocket(wsUrl); // Returns WRONG object type
    
    // This fails because 'client' is not an EventEmitter
    client.on('message', (data) => this.handleMessage(data));
    client.on('error', (err) => this.handleError(err));
    
    return client;
  }
}

依存関係のコンテキスト

wsライブラリ(または同等のもの)は、以下のメソッドを持つオブジェクトを返す必要があります:

  • on(event: string, listener: Function): this
  • once(event: string, listener: Function): this
  • off(event: string, listener: Function): this
  • send(data: string | ArrayBuffer): void

返されたオブジェクトが.on()を欠いている場合、チャンネルアダプタはバージョン間で変更されたか、依存関係のバージョン不一致により戻り値の型が変更された可能性があります。

バージョンの相関

このリグレッションはOpenClaw 2026.2.26で発生しており、以下のいずれかの最近の変更を示唆しています:

  • Feishuチャンネルアダプタのコード
  • WebSocketライブラリの依存関係バージョン
  • モジュール解決に影響するビルド/バンドリングプロセス

🛠️ 解決手順

方法1: OpenClawをダウングレードする(即座の安定化)

即座に本番環境の安定性が必要な場合は、正常に動作することが確認されているバージョンにダウングレードしてください:

# Stop OpenClaw service
sudo systemctl stop openclaw  # Linux
# or
launchctl unload ~/Library/LaunchAgents/com.openclaw.plist  # macOS

# Install previous stable version
npm install -g [email protected]

# Restart service
sudo systemctl start openclaw
# or
launchctl load ~/Library/LaunchAgents/com.openclaw.plist

方法2: HTTPロングポーリングモードに切り替え(推奨)

WebSocketモードは不安定なため、暫定的な回避策としてHTTPロングポーリングに切り替えます:

{
  "channels": {
    "feishu": {
      "enabled": true,
      "dmPolicy": "pairing",
      "mode": "polling",
      "accounts": {
        "default": {
          "appId": "cli_a90c15147a38dcb3",
          "appSecret": "***",
          "botName": "Claw",
          "pollingIntervalMs": 30000
        }
      }
    }
  }
}

注意: 設定フィールドmodeが認識されない場合は、方法3に進んでください。

方法3: 手動パッチを適用(暫定的な修正)

Feishuチャンネルアダプタのソースファイルを特定してパッチを適用します:

# Locate the Feishu channel adapter
find /usr/local/lib/node_modules/openclaw -name "feishu*.js" 2>/dev/null
# or
find ~/.openclaw -name "feishu*.js" 2>/dev/null

# Common paths:
# /usr/local/lib/node_modules/openclaw/dist/gateway/channels/feishu/index.js
# ~/.openclaw/plugins/feishu/dist/index.js

WebSocket初期化セクションに以下のパッチを適用します:

// BEFORE (buggy):
const ws = new WebSocket(url);
ws.on('message', handler);

// AFTER (patched):
const WebSocket = require('ws');
const ws = new WebSocket(url);

// Verify the client has the expected API, wrap if necessary
if (typeof ws.on !== 'function') {
  // Fallback: use EventEmitter-style wrapper
  const { EventEmitter } = require('events');
  const client = new EventEmitter();
  
  ws.onmessage = (event) => client.emit('message', event.data);
  ws.onerror = (event) => client.emit('error', event);
  ws.onopen = (event) => client.emit('open', event);
  ws.onclose = (event) => client.emit('close', event);
  
  // Replace ws with wrapped client
  Object.assign(ws, client);
}

方法4: WebSocketライブラリオーバーライドを強制(上級者向け)

依存関係のバージョン競合が疑われる場合、正しいWebSocket実装を強制的にロードします:

# Check current ws dependency version
cd /usr/local/lib/node_modules/openclaw
npm ls ws

# Install specific compatible version
npm install [email protected] --save

OpenClaw設定(~/.openclaw/config.json)に以下を追加します:

{
  "feishu": {
    "websocketOptions": {
      "resolveSocket": true,
      "library": "ws"
    }
  }
}

🧪 検証

修正の成功を確認

いずれかの修正方法を適用した後、Feishuチャンネルが正常に 연결되는지 확인합니다:

Step 1: OpenClawサービスを再起動する

# Linux
sudo systemctl restart openclaw

# macOS
launchctl unload ~/Library/LaunchAgents/com.openclaw.plist
launchctl load ~/Library/LaunchAgents/com.openclaw.plist

# Or via PM2 (if using process manager)
pm2 restart openclaw

Step 2: チャンネルステータスを確認する

openclaw status --channel feishu

# Expected output:
# feishu[default]: connected
# feishu[default]: mode: websocket  # or "polling" if using Method 2
# feishu[default]: uptime: 0d 0h 1m

Step 3: WebSocket接続を確認する(WebSocketモードのみ)

# Check for active WebSocket connection on port 9000 (default)
lsof -i :9000 | grep openclaw
# or
netstat -tlnp | grep 9000

# Expected: LISTEN or ESTABLISHED state

Step 4: インバウンドメッセージ受信をテストする

Feishuユーザーからボットにテストメッセージを送信します:

# Monitor logs for incoming message
openclaw logs --follow --filter "feishu.*incoming"

# Send a message from Feishu app to the bot
# Expected log entry:
# {"subsystem":"gateway/channels/feishu","1":"feishu[default]: incoming message from user ${userId}"}
# {"subsystem":"gateway/channels/feishu","1":"feishu[default]: message processed successfully"}

Step 5: 再起動ループがないことを確認する

# Check process uptime
pm2 list
# or
ps aux | grep openclaw

# Expected: stable uptime without auto-restart entries in logs

成功時のログシーケンス

{"subsystem":"gateway/channels/feishu","1":"starting feishu[default] (mode: websocket)"}
{"subsystem":"gateway/channels/feishu","1":"feishu[${accountId}]: bot open_id resolved: ${botOpenId}"}
{"subsystem":"gateway/channels/feishu","1":"feishu[default]: WebSocket connected"}
{"subsystem":"gateway/channels/feishu","1":"feishu[default]: channel ready"}

終了コードの検証

# Check that the process is stable (no rapid exit)
echo $?
# Expected: 0 (process running)
# If channel is working, no 'exited' messages should appear

⚠️ よくある落とし穴

  • 設定のキャッシュ: OpenClawはチャンネル設定をキャッシュする可能性があります。設定変更後は常にサービスを再起動し、問題が続く場合は`~/.openclaw/cache/`を削除してください。
  • ポーリングモードが認識されない: `mode: "polling"`設定フィールドはv2026.2.26に存在しない可能性があります。動作を前提とする前に、openclaw config schema channels.feishuでチャンネルスキーマを確認してください。
  • WebSocketライブラリのバージョン競合: OpenClawがグローバルにインストールされ、プロジェクトローカルの依存関係と一緒に使用されている場合、npmが異なるバージョンの`ws`を解決する可能性があります。両方のコンテキストでnpm ls wsを使用して監査してください。
  • Node.jsバージョンの非互換性: Node v25.6.0は非常に新しいリリースです。一部のネイティブWebSocketアドオンがこのバージョン向けにプリビルドされていない可能性があります。Node v22.x LTSを使用することを回避策として検討してください。
  • macOS ARM64ビルドアーティファクト: Apple Siliconでは、x86_64ビルドからのキャッシュされたネイティブモジュールがサイレントな失敗を引き起こす可能性があります。WebSocketライブラリの変更後はnpm rebuildを実行してください。
  • Docker環境の分離: DockerでOpenClawを実行している場合、WebSocketライブラリがコンテナ内にインストールされていることを確認し、ホストからマウントしないでください。ボリュームマウントはnode_modulesを互換性のないビルドで上書きする可能性があります。
  • Feishu APIレート制限: 再起動ループ中、複数の再接続試行がFeishuのAPIレート制限をトリガーし、二次的な認証失敗を引き起こす可能性があります。再起動試行を制限するか、バックオフを実装してください。
  • 認証情報のローテーション: Feishu Open PlatformでappSecret最近ローテーションされた場合、設定内のキャッシュされた認証情報が古くなっている可能性があります。設定ファイルで認証情報を再入力してください。
  • チャンネル優先順位の競合: 複数のFeishuアカウントが定義されている場合、チャンネルが誤ったアカウントを最初に初期化しようとする可能性があります。チャンネルレベルで"defaultAccount": "default"を明示的に設定してください。

🔗 関連するエラー

文脈的なエラーリファレンス

  • EADDRINUSE 9000: WebSocketポートの競合。別のプロセスがFeishu WebSocketゲートウェイポートを使用していることを示します。lsof -i :9000で確認してください。
  • WebSocket connection failed: 401 Unauthorized: Feishuアプリの認証情報(appId/appSecret)が無効または期限切れです。Feishu Open Platformで認証情報を確認してください。
  • Feishu API error: app_access_token invalid: トークンの更新失敗。チャンネルが有効なアクセストークンを取得できません。システム時刻の同期を確認してください。
  • channel exited: UnhandledPromiseRejection: チャンネルアダプタでの非同期初期化の失敗。プロミスが適切に処理されていない場合、client.onエラーの前兆となる可能性があります。
  • auto-restart loop detected: 高速再起動サイクルに対するOpenClawの組み込み保護。2026.2.26では10回の失敗試行後に表示されます。openclaw debugを使用してバイパスしてください。
  • Cannot find module 'ws': WebSocketの依存関係が欠落しています。npm install--omit=optionalで実行された場合に発生します。npm installで再インストールしてください。
  • ECONNREFUSED: Feishu WebSocketゲートウェイに到達できません。ファイアウォールルールと企業プロキシ設定を確認してください。
  • Historical: feishu channel not starting after v2025.x update: 以前文書化された異なるエラーメッセージを持つリグレッション。FeishuチャンネルWebSocket実装の継続的な安定性問題を示しています。

エビデンスとソース

このトラブルシューティングガイドは、FixClaw Intelligence パイプラインによってコミュニティの議論から自動的に合成されました。