mastra-ai/mastra · error

No adapter for platform "${platform}"

Error message

No adapter for platform "${platform}"

What it means

When AgentChannels processes an incoming platform event, it looks up the registered adapter by the event adapter's platform name. If the event's platform has no matching entry in this.adapters, it throws, because messages from that platform cannot be handled.

Source

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

        if (!actionId.startsWith('tool_approve:') && !actionId.startsWith('tool_deny:')) return;
        try {
          const approved = actionId.startsWith('tool_approve:');
          const toolCallId = actionId.split(':')[1];
          if (!toolCallId) {
            this.log('info', `Missing toolCallId in action event actionId=${actionId}`);
            return;
          }

          const chatThread = event.thread as Thread | null;
          if (!chatThread) {
            this.log('info', `No thread in action event for toolCallId=${toolCallId}`);
            return;
          }
          const platform = event.adapter.name;
          const messageId = event.messageId;
          const adapter = this.adapters[platform];
          const adapterConfig = this.adapterConfigs[platform];
          if (!adapter) throw new Error(`No adapter for platform "${platform}"`);

          const externalThreadId = this.resolveExternalThreadId({ platform, chatThread, messageId });
          const { thread: mastraThread } = await this.findThreadMapping({
            externalThreadId,
            channelId: chatThread.channelId,
            platform,
            mastra,
          });
          if (!mastraThread) {
            // Approval cards can only continue runs on threads created by an
            // earlier message. Do not mint a replacement from the clicker's
            // identity when that durable mapping is missing.
            this.log('warn', `No mapped channel thread found for tool approval action toolCallId=${toolCallId}`);
            return;
          }

          // Look up the runId for this toolCallId. Prefer the in-memory
          // `pendingApprovalCards` map (set when the approval card was posted)

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Register an adapter for that platform key in the AgentChannels `adapters` config
  2. Ensure the adapter's `name` property matches the key it is registered under
  3. Check webhook routing so events only reach the channels instance that registered the matching adapter

Example fix

// before
new AgentChannels({ adapters: { slack: slackAdapter } }); // event from 'teams' throws
// after
new AgentChannels({ adapters: { slack: slackAdapter, teams: teamsAdapter } });
Defensive patterns

Strategy: validation

Validate before calling

const platform = event.adapter.name;
if (!(platform in channels.adapters)) {
  console.warn(`Dropping event from unregistered platform: ${platform}`);
  return;
}

Type guard

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

Try / catch

try {
  await handleChannelEvent(event);
} catch (err) {
  if (err instanceof Error && /^No adapter for platform/.test(err.message)) {
    logger.warn({ platform: event.adapter.name }, 'event dropped: no adapter');
  } else throw err;
}

Prevention

When it happens

Trigger: A channel event arrives (e.g. via inbound webhook dispatch) whose adapter.name is not among the adapters registered on the AgentChannels instance — e.g. the event was routed to the wrong channels instance, or the adapter was registered under a different name/platform key.

Common situations: Registering an adapter with `adapters: { slack: slackAdapter }` but events arrive labeled 'slack-rtm' or 'teams'; multiple channel deployments sharing one webhook URL; renaming a platform key without redeploying the sender side.

Related errors


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