Skip to content

Bug: Slack plugin eagerly resolves SecretRef tokens at register time, crashing CLI for all agents/* commands #63937

@oliviercp

Description

@oliviercp

Summary

Any CLI command under openclaw agents (e.g. agents add, agents list) fails with a fatal PluginLoadFailureError when the Slack channel's botToken or appToken are stored as SecretRef objects (the default when secrets are configured via the file:local provider). The running gateway process is unaffected because it holds a resolved in-memory snapshot, but the CLI is a separate process that reads raw openclaw.json and crashes before the command can execute.

Steps to Reproduce

  1. Configure a Slack channel account with token secrets stored as SecretRef (e.g. file:local:/SLACK_BOT_TOKEN):
    "channels": {
      "slack": {
        "accounts": {
          "default": {
            "botToken": { "source": "file", "provider": "local", "id": "/SLACK_BOT_TOKEN" },
            "appToken": { "source": "file", "provider": "local", "id": "/SLACK_APP_TOKEN" }
          }
        }
      }
    }
  2. Run any agents subcommand:
    openclaw agents add myagent --workspace ~/.openclaw/workspace-myagent
    openclaw agents list
    

Observed Behavior

[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: ...

The process exits with code 1. No agent command can run.

Expected Behavior

The Slack plugin's register phase should not attempt to resolve tokens. Token resolution should be deferred to the actual request handler (i.e. when a Slack event arrives), not at plugin registration time. The CLI should be able to execute agents commands regardless of whether channel secrets are resolvable.

Root Cause Analysis

The call chain that causes the crash:

  1. command-execution-startup.js — the agents command path sets loadPlugins: "always", so every openclaw agents … invocation force-loads every plugin including Slack.
  2. runtime-registry-loader.js — CLI plugin loading runs with throwOnLoadError: true, making Slack's register-phase throw fatal.
  3. extensions/slack/index.jsregisterSlackPluginHttpRoutes — calls resolveSlackAccount({cfg, accountId}) eagerly while registering HTTP routes.
  4. accounts.jsresolveSlackBotToken(merged.botToken, …)normalizeResolvedSecretInputString — if merged.botToken is still a SecretRef object (not yet resolved), throws the "unresolved SecretRef" error.

The token is read from raw openclaw.json by the CLI, which has no access to the gateway's runtime secret-resolution snapshot.

Why Existing Escape Hatches Don't Work

Attempted workaround Why it fails
Set SLACK_BOT_TOKEN env var accounts.js evaluates the SecretRef from config before the env fallback; throws before checking env
Set channels.slack.enabled: false registerSlackPluginHttpRoutes iterates DEFAULT_ACCOUNT_ID unconditionally regardless of enabled
Remove "slack" from plugins.allow The plugin is also triggered by the channels.slack config block; removing from allowlist alone is insufficient
OPENCLAW_DISABLE_BUNDLED_PLUGINS=1 Invalidates the entire config (channels.slack: unknown channel id)

Workaround

Temporarily replace the SecretRef objects in openclaw.json with dummy string values, run the CLI command, then restore the original SecretRef objects. The running gateway is unaffected (it holds its own in-memory resolved state and does not watch openclaw.json).

Proposed Fix

In the Slack plugin's register hook, defer all token reads to the actual request handler. The route path should be registered unconditionally; resolveSlackAccount should only be called when an inbound Slack event is being processed, at which point the gateway runtime snapshot is available for secret resolution.

Environment

  • OpenClaw version: 2026.4.9 (0512059)
  • Platform: macOS (darwin 24.6.0)
  • Secret provider: file:local
  • Command that triggered the error: openclaw agents add dasher --workspace ~/.openclaw/workspace-dasher

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions