April 16, 2026 • Versión: 2026.4.9

El plugin de Slack falla al cargar con tokens SecretRef: PluginLoadFailureError en comandos agents/*

Cuando los tokens de canales de Slack se almacenan como objetos SecretRef, el plugin de Slack los resuelve durante el registro, lo que causa que el CLI falle en todos los comandos agents/* con un PluginLoadFailureError fatal.

🔍 Síntomas

Cualquier comando CLI bajo el espacio de nombres openclaw agents termina inmediatamente con un error fatal de carga de plugin cuando los tokens de canales de Slack están configurados como objetos SecretRef. El error ocurre antes de que se ejecute la lógica del comando, dejando toda la CLI inutilizable para la gestión de agentes.

Salida de Error Principal

$ openclaw agents list
[plugins] slack failed during register from .../extensions/slack/index.js:
  Error: channels.slack.accounts.default.botToken: unresolved SecretRef "file:local:/SLACK_BOT_TOKEN".
  Resolve this command against an active gateway runtime snapshot before reading it.

[openclaw] Failed to start CLI: PluginLoadFailureError: plugin load failed: slack: ...
$
$ echo $?
1

Comandos Adicionales Afectados

$ openclaw agents add myagent --workspace ~/.openclaw/workspace-myagent
# Same PluginLoadFailureError output, exit code 1

$ openclaw agents remove myagent
# Same PluginLoadFailureError output, exit code 1

$ openclaw agents status myagent
# Same PluginLoadFailureError output, exit code 1

Patrón de Configuración que Activa el Error

El siguiente segmento de configuración de openclaw.json activa el fallo:

json { “channels”: { “slack”: { “accounts”: { “default”: { “botToken”: { “source”: “file”, “provider”: “local”, “id”: “/SLACK_BOT_TOKEN” }, “appToken”: { “source”: “file”, “provider”: “local”, “id”: “/SLACK_APP_TOKEN” } } } } } }

Distinción del Comportamiento del Gateway

El proceso del gateway en ejecución no se ve afectado por este problema. El gateway mantiene una instantánea en memoria de secretos resueltos y procesa los eventos de Slack correctamente. Solo la CLI (un proceso separado) falla porque lee la configuración sin procesar de openclaw.json sin tener acceso al contexto de resolución de secretos en tiempo de ejecución.

🧠 Causa Raíz

Cadena de Llamadas de Ejecución

El fallo es resultado de una secuencia específica de resolución eager durante el registro de plugins:

  1. Ruta de Ejecución del Comando: command-execution-startup.js establece loadPlugins: "always" para todos los subcomandos de agents, forzando la inicialización completa del plugin en cada invocación.
  2. Manejo Estricto de Errores: runtime-registry-loader.js ejecuta la carga de plugins de CLI con throwOnLoadError: true, convirtiendo cualquier error de registro de plugin en una condición fatal.
  3. El Registro de Rutas Activa la Resolución: extensions/slack/index.js llama a registerSlackPluginHttpRoutes() durante su hook de registro.
  4. Acceso Eager a Tokens: registerSlackPluginHttpRoutes() invoca resolveSlackAccount({cfg, accountId}) incondicionalmente, incluyendo para la cuenta por defecto.
  5. SecretRef Lanza Error No Resuelto: accounts.jsresolveSlackBotToken(merged.botToken, …)normalizeResolvedSecretInputString() detecta el objeto SecretRef no resuelto y lanza el error fatal.

Inconsistencia Arquitectónica

El plugin de Slack viola el principio de resolución diferida que se espera de los plugins de canales:

  • Comportamiento Esperado: El registro del plugin debe registrar rutas y preparar handlers. La resolución real de tokens debe ocurrir al procesar un evento entrante (es decir, dentro del handler de solicitud HTTP), momento en el que la instantánea del runtime del gateway está disponible.
  • Comportamiento Real: La resolución de tokens ocurre sincrónicamente durante el registro de rutas, antes de que se pueda procesar cualquier solicitud.

Por Qué la CLI No Puede Resolver Secretos

El proceso de la CLI es un ejecutable independiente que:

  1. Lee openclaw.json directamente del disco.
  2. No tiene conexión activa con el runtime del gateway.
  3. No puede acceder a la instantánea de resolución de secretos del gateway.
  4. Falla al encontrar cualquier SecretRef que no se haya resuelto a un valor de cadena concreto.

Soluciones Alternativas Insuficientes

Solución AlternativaRazón del Fallo
Establecer variable de entorno SLACK_BOT_TOKENaccounts.js evalúa la estructura SecretRef antes de verificar el fallback de entorno; lanza antes de que ocurra la resolución de entorno.
Establecer channels.slack.enabled: falseregisterSlackPluginHttpRoutes itera DEFAULT_ACCOUNT_ID incondicionalmente, ignorando la bandera enabled durante el registro.
Eliminar “slack” de plugins.allowEl plugin también es activado por el bloque de configuración channels.slack; eliminarlo solo de la lista de permitidos es insuficiente para prevenir la carga.
OPENCLAW_DISABLE_BUNDLED_PLUGINS=1Invalida toda la configuración de channels, reportando channels.slack: unknown channel id.

🛠️ Solución Paso a Paso

Opción A: Solución Alternativa Temporal (Alivio Inmediato)

Reemplazar los objetos SecretRef con valores de cadena dummy antes de ejecutar comandos CLI, luego restaurar la configuración original.

Antes (openclaw.json):

"botToken": { "source": "file", "provider": "local", "id": "/SLACK_BOT_TOKEN" },
"appToken": { "source": "file", "provider": "local", "id": "/SLACK_APP_TOKEN" }

Después (temporal):

"botToken": "xoxb-placeholder-do-not-use",
"appToken": "xapp-placeholder-do-not-use"

Ejecutar el comando CLI requerido:

openclaw agents add myagent --workspace ~/.openclaw/workspace-myagent

Restaurar los objetos SecretRef originales en openclaw.json inmediatamente después.

Opción B: Solución Alternativa Basada en Configuración

Crear un openclaw.json separado para operaciones solo de CLI que excluya completamente la configuración de Slack.

  1. Hacer copia de seguridad de la configuración actual:
cp ~/.openclaw/openclaw.json ~/.openclaw/openclaw.json.gateway
  1. Crear una configuración específica para CLI sin definiciones de canales:
cat > ~/.openclaw/openclaw-cli.json << 'EOF'
{
  "version": "2",
  "workspace": {
    "default": "~/.openclaw/workspace-default"
  },
  "plugins": {
    "allow": ["core", "agents"]
  }
}
EOF
  1. Usar la configuración específica de CLI mediante variable de entorno:
OPENCLAW_CONFIG=~/.openclaw/openclaw-cli.json openclaw agents list

Opción C: Corrección de Código (Solución Permanente)

Modificar el hook de registro del plugin de Slack para diferir la resolución de tokens.

Archivo: extensions/slack/index.js

Antes (código problemático actual):

function registerSlackPluginHttpRoutes(cfg) {
  // Eagerly resolve account during registration
  const account = resolveSlackAccount({ cfg, accountId: DEFAULT_ACCOUNT_ID });
  
  router.post('/events', async (req, res) => {
    // Handle Slack events...
  });
}

Después (resolución diferida):

function registerSlackPluginHttpRoutes(cfg) {
  // Register route unconditionally; resolve lazily on each request
  router.post('/events', async (req, res) => {
    // Resolve account only when processing an actual event
    const account = resolveSlackAccount({ cfg, accountId: DEFAULT_ACCOUNT_ID });
    
    // Handle Slack events...
  });
}

Aplicar el mismo patrón a cualquier otra ruta que acceda a tokens de cuenta (/interactions, /commands, etc.).

🧪 Verificación

Verificación de la Solución Alternativa (Opción A)

  1. Confirmar que la configuración original contiene objetos SecretRef:
$ grep -A5 '"botToken"' ~/.openclaw/openclaw.json
        "botToken": {
          "source": "file",
          "provider": "local",
          "id": "/SLACK_BOT_TOKEN"
        },
  1. Reemplazar temporalmente con cadenas de placeholder y ejecutar el comando:
$ sed -i '' 's/"botToken": { "source": "file", "provider": "local", "id": "\/SLACK_BOT_TOKEN" }/"botToken": "xoxb-placeholder"/' ~/.openclaw/openclaw.json
$ sed -i '' 's/"appToken": { "source": "file", "provider": "local", "id": "\/SLACK_APP_TOKEN" }/"appToken": "xapp-placeholder"/' ~/.openclaw/openclaw.json
$ openclaw agents list
[agent list output]
$ echo $?
0
  1. Restaurar la configuración original:
$ cp ~/.openclaw/openclaw.json.gateway ~/.openclaw/openclaw.json
# Verify restoration
$ grep -A5 '"botToken"' ~/.openclaw/openclaw.json | head -6
        "botToken": {
          "source": "file",
          "provider": "local",
          "id": "/SLACK_BOT_TOKEN"
        },

Verificación de la Corrección Permanente (Opción C)

Después de aplicar la corrección de código a extensions/slack/index.js:

  1. Reconstruir o reinstalar la CLI de OpenClaw:
$ npm run build  # or the appropriate build command for your installation
$ openclaw --version
openclaw/2026.4.9 darwin-x64 node-v22.8.0
  1. Verificar que el comando de agentes ahora funciona con la configuración SecretRef intacta:
$ openclaw agents list
[agent list output]
$ echo $?
0
  1. Confirmar que el gateway todavía procesa los eventos de Slack correctamente (si está en ejecución):
$ curl -X POST http://localhost:3000/slack/events \
  -H "Content-Type: application/json" \
  -d '{"type": "url_verification", "challenge": "test"}'
{"challenge": "test"}
  1. Verificar que no haya errores residuales en los logs:
$ tail -n 50 ~/.openclaw/logs/gateway.log | grep -i "secret\|token\|resolve"
# No error messages should appear

⚠️ Errores Comunes

Error 1: Olvidar Restaurar la Configuración

Después de usar la solución alternativa de placeholder, los usuarios frecuentemente olvidan restaurar la configuración SecretRef original. Esto causa que el gateway en ejecución recargue tokens de placeholder inválidos en el próximo reinicio.

Mitigación: Siempre hacer copia de seguridad antes de la modificación y usar operaciones atómicas:

# Atomic swap with backup
cp ~/.openclaw/openclaw.json ~/.openclaw/openclaw.json.backup && \
  sed -i 's/placeholder/dummy/' ~/.openclaw/openclaw.json && \
  openclaw agents list && \
  mv ~/.openclaw/openclaw.json.backup ~/.openclaw/openclaw.json

Error 2: Múltiples Configuraciones de CLI Causando Confusión

Los usuarios que crean una configuración separada para CLI pueden accidentalmente modificar la configuración del gateway esperando comportamiento de CLI, o viceversa.

Mitigación: Siempre usar la variable de entorno OPENCLAW_CONFIG explícitamente y verificar qué configuración está activa:

$ OPENCLAW_CONFIG=~/.openclaw/openclaw-cli.json openclaw config show | grep workspace

Error 3: Asumir que enabled: false Previene la Carga del Plugin

El plugin de Slack se carga independientemente de la bandera enabled porque el plugin es activado tanto por la lista plugins.allow como por el bloque de configuración channels.slack.

Mitigación: No depender de enabled: false para omitir la carga del plugin en el contexto de CLI.

Error 4: Soluciones Alternativas con Variables de Entorno Insuficientes

Establecer SLACK_BOT_TOKEN como variable de entorno no evita el error SecretRef porque el plugin evalúa la estructura SecretRef primero, antes de verificar los fallbacks de entorno.

Mitigación: Usar la solución alternativa de placeholder o el enfoque de configuración de CLI separada en su lugar.

Error 5: Entornos Docker/Contenedor

En despliegues contenedorizados, el proveedor de secretos file:local puede no tener acceso a las rutas del sistema de archivos host especificadas en el SecretRef.

Mitigación: Montar el directorio de secretos en el contenedor:

docker run --rm \
  -v $HOME/.openclaw:/root/.openclaw \
  -v /run/secrets:/run/secrets:ro \
  openclaw agents list

Error 6: Separadores de Ruta en Windows

En Windows, el ID del SecretRef usa barras inclinadas hacia adelante (/SLACK_BOT_TOKEN) que pueden entrar en conflicto con el análisis de rutas de Windows en algunas configuraciones.

Mitigación: Usar IDs de secreto compatibles con Windows o configurar el proveedor file:local con el mapeo de rutas apropiado.

🔗 Errores Relacionados

  • PluginLoadFailureError — Fallo genérico de carga de plugin. En este contexto, activado específicamente por la resolución eager de tokens del plugin de Slack durante el registro. Código de salida: 1.
  • channels.slack.accounts.default.botToken: unresolved SecretRef — Error específico lanzado por normalizeResolvedSecretInputString() cuando encuentra un objeto SecretRef que no se ha resuelto a un valor de cadena.
  • channels.slack: unknown channel id — Error encontrado cuando los plugins incluidos están deshabilitados pero existe configuración de channels.slack. Indica una configuración incorrecta de la variable de entorno OPENCLAW_DISABLE_BUNDLED_PLUGINS.
  • SecretRef resolution errors in other plugins — Problemas similares de resolución eager pueden existir en otros plugins de canales (por ejemplo, Microsoft Teams, Discord) si siguen el mismo patrón de registro que Slack.
  • OPENCLAW_CONFIG not found — Error cuando la ruta del archivo de configuración especificado no existe. Verificar que la ruta sea absoluta o relativa al directorio de trabajo correcto.
  • throwOnLoadError: true en contextos no-CLI — Cualquier ruta de código que invoque la carga de plugins con throwOnLoadError: true exhibirá este mismo modo de fallo, no solo la CLI. Revisar todos los puntos de llamada de runtime-registry-loader.js.

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.