Tencent/WeKnora · error
channel not found: %s
Error message
channel not found: %s
What it means
When handling an incoming message, the service first tries GetChannelAdapter(channelID); if the channel isn't loaded it attempts to load it from the DB and start it dynamically. If the DB lookup also fails (channel truly doesn't exist), this error is returned.
Source
Thrown at internal/im/service.go:1693
logger.Infof(ctx, "[IM] Skipping duplicate message: %s", msg.MessageID)
return nil
}
}
// Reject overly long messages to protect the QA pipeline
contentRunes := []rune(msg.Content)
if len(contentRunes) > maxContentLength {
logger.Warnf(ctx, "[IM] Message too long (%d runes), truncating to %d", len(contentRunes), maxContentLength)
msg.Content = string(contentRunes[:maxContentLength])
}
// Get channel config (moved before rate limit so we can reply to the user)
adapter, channel, ok := s.GetChannelAdapter(channelID)
if !ok {
// Try loading from DB (channel might have been created after service start)
ch, err := s.GetChannelByID(channelID)
if err != nil {
return fmt.Errorf("channel not found: %s", channelID)
}
// Start it dynamically
if err := s.StartChannel(ch); err != nil {
return fmt.Errorf("start channel %s: %w", channelID, err)
}
adapter, channel, ok = s.GetChannelAdapter(channelID)
if !ok {
return fmt.Errorf("channel adapter not available after start: %s", channelID)
}
}
// Resolve threadID for key building — only include in thread mode to avoid
// leaking thread scope into user-mode rate limit / inflight keys.
threadID := ""
if channel.SessionMode == string(SessionModeThread) {
threadID = msg.ThreadID
}
View on GitHub (pinned to 988cbb0330)
Solutions
- Verify the channel ID exists in the DB and re-create it if deleted
- Re-register the webhook/subscription with the correct channel ID
- Check you're pointing at the right environment/database (prod vs staging)
Defensive patterns
Strategy: fallback
Validate before calling
if _, err := svc.GetChannelByID(channelID); err != nil {
log.Printf("unknown channel %s; check webhook registration", channelID)
return
} Try / catch
adapter, channel, ok := svc.GetChannelAdapter(channelID)
if !ok {
if _, err := svc.GetChannelByID(channelID); err != nil {
// channel truly missing: log and drop the event instead of crashing
return
}
} Prevention
- Re-register webhooks whenever channels are recreated or IDs change
- Periodically reconcile platform webhook subscriptions against the channels table
- Tag events with the environment so staging webhooks don't hit prod DBs
When it happens
Trigger: A webhook/event arrives for a channelID that is neither running nor present in the database — e.g. the channel was deleted, or the ID in the platform URL is wrong.
Common situations: Stale webhooks pointing at a deleted channel; recreating a channel which changed its ID; environment mismatch (webhook registered against a different DB/stage); typo in the channel ID portion of a callback URL.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- join request not found
- rbac: resource not found
- knowledge service returned an empty result
- %w: %s
- mcp service not found
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/02596255270a577e.
Report an issue: GitHub.