mastra-ai/mastra · error

No adapter registered for platform

Error message

No adapter registered for platform "${channel.platform}"

What it means

After finding a channel context in RequestContext, getAdapterFromContext looks up this.adapters[channel.platform]. If the platform name from the context is not a registered adapter, it throws this error distinguishing it from the missing-context case: context exists, but no adapter handles that platform.

Solutions

  1. Register an adapter under the exact platform name present in the channel context
  2. Log/inspect the context's channel.platform and align adapter keys with it
  3. Normalize platform names (e.g. lowercase) when setting the channel context

Example fix

// before
ctx.set('channel', { platform: 'Slack', threadId: 'C1' }); // adapters keyed 'slack'
// after
ctx.set('channel', { platform: 'slack', threadId: 'C1' });
Defensive patterns

Strategy: validation

Validate before calling

const channel = ctx?.get('channel') as ChannelContext | undefined;
if (channel?.platform && !(channel.platform in channels.adapters)) {
  logger.warn(`Unknown platform in context: ${channel.platform}`);
  return;
}

Type guard

function isKnownPlatform(p: string, adapters: Record<string, unknown>): p is keyof typeof adapters {
  return p in adapters;
}

Try / catch

try {
  await channels.reply(message, { requestContext: ctx });
} catch (err) {
  if (err instanceof Error && /No adapter registered for platform/.test(err.message)) {
    logger.error({ platform: ctx.get('channel')?.platform }, 'platform not registered');
  } else throw err;
}

Prevention

When it happens

Trigger: RequestContext 'channel' key present with a platform value that has no entry in the AgentChannels adapters map — e.g. typo'd platform string, adapter registered under a different key, or context produced by a different channels configuration.

Common situations: Renaming adapter registration keys while old messages/contexts still carry the previous platform name; multiple channels instances with different adapter sets; hand-crafted context objects with wrong platform values.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/46ff7374c90c59e5. Report an issue: GitHub.

Appendix: source

Thrown at packages/core/src/channels/agent-channels.ts:948

    if (!this.toolsEnabled) return {};
    return this.makeChannelTools();
  }

  // ---------------------------------------------------------------------------
  // Private
  // ---------------------------------------------------------------------------

  /**
   * Resolve the adapter for the current conversation from request context.
   */
  private getAdapterFromContext(context: { requestContext?: RequestContext }): { adapter: Adapter; threadId: string } {
    const channel = context.requestContext?.get('channel') as ChannelContext | undefined;
    if (!channel?.platform || !channel?.threadId) {
      throw new Error('No channel context — cannot determine platform or thread');
    }
    const adapter = this.adapters[channel.platform];
    if (!adapter) {
      throw new Error(`No adapter registered for platform "${channel.platform}"`);
    }
    return { adapter, threadId: channel.threadId };
  }

  /**
   * Derive the three per-event shapes we hand off to downstream systems from one set of
   * inputs. Keeping this in one place ensures the LLM (`attributes`), input processors
   * (`requestContext`), and memory (`metadata`) all see consistent author / thread facts.
   *
   *   - `channelContext` — goes on `requestContext` under the 'channel' key, consumed by
   *     `ChatChannelProcessor` and other input processors.
   *   - `attributes` — serialized as XML on the user message element the LLM sees (e.g. on
   *     `<user messageId=... authorId=... />`). Strings only.
   *   - `providerOptions` — written to the stored message's `content.providerMetadata`
   *     under `mastra.channels.<platform>` so UI/query callers can read author/channel
   *     facts off the message (e.g. show a Slack icon + author name) without unpacking
   *     the signal envelope. The LLM ignores `providerOptions.mastra.*` since only
   *     provider-keyed entries (openai, anthropic, …) are forwarded to the model.

View on GitHub (pinned to 75dd419e61)