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
- Register the adapter factory for that platform when constructing the IM service (e.g. im.NewService(..., telegram.NewFactory(), qqbot.NewFactory()))
- Fix the channel's platform string to match a registered platform exactly
- 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
- Register every adapter factory at service construction and keep the list in one place
- Use constants for platform names instead of free-form strings in configs
- Add a startup self-test that starts all configured channels so missing factories fail fast
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.