[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 functionContexto 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
- Inicialización del canal: OpenClaw instancia el adaptador del canal Feishu en modo WebSocket.
- Creación del cliente: El adaptador llama al constructor de la biblioteca WebSocket.
- 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
- Fallo en la vinculación de eventos: La llamada a `client.on('message', handler)` lanza
TypeError: client.on is not a function. - 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): thisonce(event: string, listener: Function): thisoff(event: string, listener: Function): thissend(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 [email protected]
# Restart service
sudo systemctl start openclaw
# or
launchctl load ~/Library/LaunchAgents/com.openclaw.plistMé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.jsAplicar 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 [email protected] --saveAgregar 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 openclawPaso 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 1mPaso 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 statePaso 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 logsSecuencia 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.feishuantes 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 wsen 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 rebuilddespué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_modulescon 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 conlsof -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 errorclient.onsi 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. Usaropenclaw debugpara omitir.Cannot find module 'ws': Dependencia WebSocket faltante. Ocurre sinpm installse ejecutó con--omit=optional. Reinstalar connpm 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.