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
- Register at least one channel.onMessage(...) or channel.onMention(...) handler before start
- If the channel is intentionally passive, use an adapter without supportsMessageEvents (or remove it)
- 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
- Register onMessage/onMention in the same setup function that builds the channel
- Add a startup lint: message-capable channels require at least one message handler
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
- channel not started: the runner must start the channel (chan
- channel.transcripts is available after the runner starts the
- channel.ɵruntime.addAdapter must be called before channel.ɵr
- channel ${channelId} is not sendable
AI-assisted analysis of CopilotKit/CopilotKit@68fbe97d87 (2026-08-27).
Data as JSON: /api/errors/52d2f1b8d2c38729.
Report an issue: GitHub.