Tencent/WeKnora · error

no adapter factory for platform: %s

Error message

no adapter factory for platform: %s

What it means

StartChannel looks up the platform's adapter factory in s.adapterFactories (populated at service construction via registered factories). If no factory is registered for channel.Platform, the channel cannot be started and this error is returned.

Source

Thrown at internal/im/service.go:1112

		logger.Warnf(context.Background(), "[IM] Reload channel %s after %s failed: %v", channelID, reason, err)
	}
}

// StartChannel creates and registers an adapter for the given channel.
// For WebSocket channels with Redis available, only one instance acquires
// the leader lock and opens the connection; other instances periodically
// retry so they can take over if the leader dies.
func (s *Service) StartChannel(channel *IMChannel) error {
	if s.stopped.Load() {
		return fmt.Errorf("im service is stopped")
	}

	s.mu.Lock()
	s.stopLeaderRetryLocked(channel.ID)
	factory, ok := s.adapterFactories[channel.Platform]
	if !ok {
		s.mu.Unlock()
		return fmt.Errorf("no adapter factory for platform: %s", channel.Platform)
	}
	// Stop existing channel if running
	if existing, ok := s.channels[channel.ID]; ok {
		s.stopChannelLocked(channel.ID, existing)
	}
	s.mu.Unlock()

	// For WebSocket / long-poll channels, try leader election to avoid
	// duplicate connections. Only one instance should actively poll or
	// maintain a persistent connection for each channel.
	if (channel.Mode == "websocket" || channel.Mode == "longpoll") && s.redis != nil {
		acquired := s.tryAcquireWSLeader(channel.ID)
		if !acquired {
			logger.Infof(context.Background(),
				"[IM] Channel %s %s owned by another instance, will retry", channel.ID, channel.Mode)
			s.scheduleWSLeaderRetry(channel)
			return nil
		}

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Register the adapter factory for that platform when constructing the IM service (e.g. im.NewService(..., telegram.NewFactory(), qqbot.NewFactory()))
  2. Fix the channel's platform string to match a registered platform exactly
  3. Import the adapter package so its factory registration side-effect runs

Example fix

// before
svc := im.NewService(cfg, store) // telegram factory missing
// after
svc := im.NewService(cfg, store, telegram.NewFactory(), qqbot.NewFactory())
Defensive patterns

Strategy: validation

Validate before calling

known := map[string]bool{"telegram":true,"qqbot":true /* registered platforms */}
if !known[channel.Platform] {
    return fmt.Errorf("platform %q is not registered", channel.Platform)
}

Try / catch

if err := svc.StartChannel(ch); err != nil {
    if strings.HasPrefix(err.Error(), "no adapter factory") {
        log.Printf("platform %s not registered; check factory wiring", ch.Platform)
    }
}

Prevention

When it happens

Trigger: Calling StartChannel (or the dynamic-start path when a message arrives for an unknown channel) with a channel whose Platform string has no registered factory — e.g. typo'd platform name or an adapter package never wired in.

Common situations: Misspelled platform in channel config ("telegramm", "whatsap"); forgetting to import/ register an adapter package (blank import of the factory); new platform added to config before code deploy.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/d58600d33257efd4. Report an issue: GitHub.