April 21, 2026 • Versión: 2026.2.26

[client.on no es una función en canal Feishu] - Feishu Channel WebSocket Mode: client.on is not a function

El canal Feishu falla al iniciar con 'client.on is not a function' debido a un fallo en la inicialización del cliente WebSocket en OpenClaw 2026.2.26.


🔍 Síntomas

Manifestación principal del error

El canal de Feishu se termina inmediatamente tras la inicialización con un TypeError:

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

Contexto de ejecución

El error ocurre durante la fase de apretón de manos WebSocket, como se evidencia en la secuencia de registros:

{"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"}

Observaciones diagnósticas

  • La resolución de identidad del bot se completa exitosamente: La entrada de registro `open_id` confirma que la autenticación de API (appId/appSecret) funciona correctamente.
  • Comunicación saliente no afectada: El envío de mensajes a través del canal de Feishu funciona correctamente.
  • Procesamiento entrante fallido: No se procesan mensajes entrantes de usuarios de Feishu.
  • Bucle de reintento iniciado: El canal entra en un ciclo de reinicio continuo con retroceso exponencial.

Comandos de inspección CLI

Para diagnosticar manualmente esta condición:

# 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

🧠 Causa raíz

Punto de fallo arquitectónico

El error client.on is not a function se origina de una inicialización incorrecta del cliente WebSocket en el adaptador del canal Feishu. El código intenta adjuntar listeners de eventos a un objeto cliente que carece de la API compatible con EventEmitter esperada.

Análisis de la secuencia de fallo

  1. Inicialización del canal: OpenClaw instancia el adaptador del canal Feishu en modo WebSocket.
  2. Creación del cliente: El adaptador llama al constructor de la biblioteca WebSocket.
  3. Desajuste de API: El código espera un objeto WebSocket estándar con métodos `.on(event, handler)`, pero recibe cualquiera de estos:
    • Un objeto de respuesta de cliente HTTP sin procesar
    • Una conexión WebSocket envuelta incorrectamente
    • Una instancia de WebSocketShim con superficie de API incompatible
  4. Fallo en la vinculación de eventos: La llamada a `client.on('message', handler)` lanza TypeError: client.on is not a function.
  5. Terminación elegante: El canal captura el error y sale con el mensaje reportado.

Ruta probable del código

La inicialización problemática probablemente sigue este patrón:

// Hipotética implementación incorrecta (simplificada)
const WebSocket = require('ws');

class FeishuChannel {
  async connect(config) {
    const wsUrl = await this.obtainWebSocketEndpoint(config);
    
    // ERROR: Usando el constructor WebSocket directamente en lugar de la conexión adecuada
    const client = new WebSocket(wsUrl); // Retorna el TIPO DE OBJETO INCORRECTO
    
    // Esto falla porque 'client' no es un EventEmitter
    client.on('message', (data) => this.handleMessage(data));
    client.on('error', (err) => this.handleError(err));
    
    return client;
  }
}

Contexto de dependencias

La biblioteca ws (o equivalente) debe retornar un objeto con estos métodos:

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

Si el objeto retornado carece de .on(), el adaptador del canal probablemente fue modificado entre versiones, o una discrepancia de versión de dependencia alteró el tipo de retorno.

Correlación de versiones

La regresión apareció en OpenClaw 2026.2.26, indicando un cambio reciente en:

  • El código del adaptador del canal Feishu
  • Una versión de la biblioteca WebSocket
  • El proceso de construcción/empaquetado que afecta la resolución de módulos

🛠️ Solución paso a paso

Método 1: Retroceder OpenClaw (Alivio inmediato)

Si se requiere estabilidad inmediata en producción, retroceder a una versión que funcionaba:

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

# Install previous stable version
npm install -g openclaw@2026.2.20

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

Método 2: Cambiar a modo HTTP Long-Polling (Recomendado)

El modo WebSocket es inestable; cambiar a HTTP long-polling como solución alternativa provisional:

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

Nota: Si el campo de configuración mode no es reconocido, proceda al Método 3.

Método 3: Aplicar parche manual (Corrección temporal)

Identificar y parchear el archivo fuente del adaptador del canal 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

Aplicar el siguiente parche a la sección de inicialización de WebSocket:

// ANTES (con errores):
const ws = new WebSocket(url);
ws.on('message', handler);

// DESPUÉS (parcheado):
const WebSocket = require('ws');
const ws = new WebSocket(url);

// Verificar que el cliente tiene la API esperada, envolver si es necesario
if (typeof ws.on !== 'function') {
  // Respaldo: usar wrapper estilo EventEmitter
  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);
  
  // Reemplazar ws con cliente envuelto
  Object.assign(ws, client);
}

Método 4: Forzar anulación de biblioteca WebSocket (Avanzado)

Si se sospecha un conflicto de versión de dependencia, forzar la carga de la implementación WebSocket correcta:

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

# Install specific compatible version
npm install ws@8.17.0 --save

Agregar a la configuración de OpenClaw (~/.openclaw/config.json):

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

🧪 Verificación

Confirmar éxito de la corrección

Después de aplicar cualquier método de corrección, verificar que el canal de Feishu se conecta exitosamente:

Paso 1: Reiniciar servicio 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

Paso 2: Verificar estado del canal

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

Paso 3: Verificar conexión WebSocket (solo modo 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

Paso 4: Probar recepción de mensajes entrantes

Enviar un mensaje de prueba desde un usuario de Feishu al bot:

# 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"}

Paso 5: Verificar que no hay bucle de reinicio

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

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

Secuencia de registros exitosa esperada

{"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"}

Verificación de código de salida

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

⚠️ Errores comunes

  • Almacenamiento en caché de configuración: OpenClaw puede almacenar en caché las configuraciones de canal. Siempre reinicie el servicio después de cambios de configuración, y elimine `~/.openclaw/cache/` si los problemas persisten.
  • Modo polling no reconocido: El campo de configuración `mode: "polling"` puede no existir en v2026.2.26. Verifique el esquema del canal con openclaw config schema channels.feishu antes de asumir que funcionará.
  • Conflictos de versión de biblioteca WebSocket: Si OpenClaw está instalado globalmente junto con dependencias locales del proyecto, npm puede resolver diferentes versiones de `ws`. Audite con npm ls ws en ambos contextos.
  • Incompatibilidad de versión de Node.js: Node v25.6.0 es una versión muy reciente. Algunos addons WebSocket nativos pueden no estar preconstruidos para esta versión. Considere usar Node v22.x LTS como solución alternativa.
  • Artefactos de compilación ARM64 en macOS: En Apple Silicon, los módulos nativos en caché de compilaciones x86_64 pueden causar fallos silenciosos. Ejecute npm rebuild después de cualquier cambio en la biblioteca WebSocket.
  • Aislamiento de entorno Docker: Si ejecuta OpenClaw en Docker, asegúrese de que la biblioteca WebSocket esté instalada dentro del contenedor, no montada desde el host. Los montajes de volumen pueden sobrescribir node_modules con compilaciones incompatibles.
  • Limitación de tasa de API de Feishu: Durante el bucle de reinicio, múltiples intentos de reconexión pueden activar los límites de tasa de API de Feishu, causando fallos de autenticación secundarios. Limite los intentos de reinicio o implemente retroceso.
  • Rotación de credenciales: Si el appSecret fue rotado recientemente en la Plataforma Abierta de Feishu, las credenciales en caché en la configuración pueden estar obsoletas. Reingrese las credenciales en el archivo de configuración.
  • Conflictos de prioridad de canal: Si se definen múltiples cuentas de Feishu, el canal puede intentar inicializar primero la cuenta incorrecta. Establezca explícitamente "defaultAccount": "default" a nivel de canal.

🔗 Errores relacionados

Referencias de error contextuales

  • EADDRINUSE 9000: Conflicto de puerto WebSocket. Indica que otro proceso está usando el puerto de puerta de enlace WebSocket de Feishu. Verificar con lsof -i :9000.
  • WebSocket connection failed: 401 Unauthorized: Las credenciales de la aplicación Feishu (appId/appSecret) son inválidas o expiraron. Verificar credenciales en la Plataforma Abierta de Feishu.
  • Feishu API error: app_access_token invalid: Fallo de renovación de token. El canal no puede obtener un token de acceso válido. Verificar sincronización de hora del sistema.
  • channel exited: UnhandledPromiseRejection: Fallo de inicialización asíncrona en el adaptador del canal. Puede ser un precursor del error client.on si las promesas no se manejan correctamente.
  • auto-restart loop detected: Protección integrada de OpenClaw contra ciclos de reinicio rápido. Aparece después de 10 intentos fallidos en 2026.2.26. Usar openclaw debug para omitir.
  • Cannot find module 'ws': Dependencia WebSocket faltante. Ocurre si npm install se ejecutó con --omit=optional. Reinstalar con npm install.
  • ECONNREFUSED: La puerta de enlace WebSocket de Feishu es inaccesible. Verificar reglas de firewall y configuración de proxy corporativo.
  • Histórico: canal feishu no iniciando después de actualización v2025.x: Regresión documentada anteriormente con diferente mensaje de error. Indica problemas de estabilidad continuos con la implementación WebSocket del canal Feishu.

Evidencia y fuentes

Esta guía de solución de problemas fue sintetizada automáticamente por la tubería de inteligencia de FixClaw a partir de las discusiones de la comunidad.