CopilotKit/CopilotKit · error

channel "${opts.name ?? "(unnamed)"}" must register onMentio

Error message

channel "${opts.name ?? "(unnamed)"}" must register onMention or onMessage before activation

What it means

A channel whose adapters support message events (supportsMessageEvents) is considered dead if it registers no onMention and no onMessage handlers — it would receive messages and do nothing. start() throws this guard so the runtime reports failure instead of a silently idle channel.

Source

Thrown at packages/channels-core/src/create-channel.ts:1366

          );
        }
        adapters.push(adapter);
      },
      async start() {
        // Idempotent: a second start() must not re-resolve the backend and
        // rebuild Transcripts/Telemetry/ActionRegistry or re-call adapter.start()
        // — with a MemoryStore that wipes all lock/dedup/transcript/action state,
        // and real adapters would connect/port-bind twice.
        if (started) return;
        if (componentConfigurationError) throw componentConfigurationError;
        if (
          adapters.some(
            (adapter) => adapter.capabilities.supportsMessageEvents,
          ) &&
          mentionHandlers.length === 0 &&
          messageHandlers.length === 0
        ) {
          throw new Error(
            `channel "${opts.name ?? "(unnamed)"}" must register onMention or onMessage before activation`,
          );
        }
        started = true;
        // Resolve persistence now that all adapters (including any attached via
        // addAdapter) are known, then build the transcript store, action
        // registry, and register components against it.
        backend = resolveBackend(cfg.adapter, adapters);
        transcripts = new Transcripts(backend, cfg.transcripts ?? {});
        const tel = new ChannelTelemetry({
          backend,
          packageName: pkg.name,
          packageVersion: pkg.version,
        });
        telemetry = tel;
        const registryInstance = new ActionRegistry({
          store:
            opts.actionStore ??

View on GitHub (pinned to 68fbe97d87)

Solutions

  1. Register at least one channel.onMessage(...) or channel.onMention(...) handler before start
  2. If the channel is intentionally passive, use an adapter without supportsMessageEvents (or remove it)
  3. Give the channel a (possibly temporary) name to make the error message identify it

Example fix

// before
const ch = createChannel({ name: "bot", identifyUser: "platform", agent });
ch.onCommand("help", handler);
await runner.start(ch); // throws

// after
ch.onMessage(thread => { /* ... */ });
await runner.start(ch);
Defensive patterns

Strategy: validation

Validate before calling

if (channel.commandNames.length > 0 && !hasMessageHandlers(channel)) {
  channel.onMessage(() => {}); // or add a real handler
}

Prevention

When it happens

Trigger: Creating a channel with a message-capable adapter (e.g. Slack/Discord) but only registering onCommand or onAction handlers; forgetting to copy handler registration lines when refactoring a channel; registering handlers after start.

Common situations: Commands-only bots on messaging platforms; refactoring that moves onMessage into a conditionally-skipped branch; empty placeholder channels left in config.

Related errors


AI-assisted analysis of CopilotKit/CopilotKit@68fbe97d87 (2026-08-27). Data as JSON: /api/errors/52d2f1b8d2c38729. Report an issue: GitHub.