mattermost-community/focalboard · error
cannot fetch channel member for user %s: %w
Error message
cannot fetch channel member for user %s: %w
What it means
SubscriptionDeliverSlackAttachments returns this error when verifying the subscriber via GetUserByID fails with an error other than not-found (not-found subscribers are silently skipped). The wrapped error indicates the subscriber's user record could not be retrieved from the Mattermost plugin API, so the subscription notification cannot be delivered. Note the message says 'channel member' but the actual call is a user lookup — the naming is misleading.
Source
Thrown at server/services/notify/plugindelivery/subscription_deliver.go:29
mm_model "github.com/mattermost/mattermost/server/public/model"
)
var (
ErrUnsupportedSubscriberType = errors.New("invalid subscriber type")
)
// SubscriptionDeliverSlashAttachments notifies a user that changes were made to a block they are subscribed to.
func (pd *PluginDelivery) SubscriptionDeliverSlackAttachments(teamID string, subscriberID string, subscriptionType model.SubscriberType,
attachments []*mm_model.SlackAttachment) error {
// check subscriber is member of channel
_, err := pd.api.GetUserByID(subscriberID)
if err != nil {
if model.IsErrNotFound(err) {
// subscriber is not a member of the channel; fail silently.
return nil
}
return fmt.Errorf("cannot fetch channel member for user %s: %w", subscriberID, err)
}
channelID, err := pd.getDirectChannelID(teamID, subscriberID, subscriptionType, pd.botID)
if err != nil {
return err
}
post := &mm_model.Post{
UserId: pd.botID,
ChannelId: channelID,
}
mm_model.ParseSlackAttachment(post, attachments)
_, err = pd.api.CreatePost(post)
return err
}
View on GitHub (pinned to a84bbb65e3)
Solutions
- Check the wrapped cause to distinguish transient API errors from persistent user problems
- Clean up subscription records referencing deleted users
- Retry delivery on transient plugin API failures
- Verify plugin API connectivity and bot permissions
Example fix
// before
if _, err := pd.api.GetUserByID(subscriberID); err != nil {
return fmt.Errorf("cannot fetch channel member for user %s: %w", subscriberID, err)
}
// after
if _, err := pd.api.GetUserByID(subscriberID); err != nil {
if model.IsErrNotFound(err) {
return nil
}
if errors.Is(err, context.DeadlineExceeded) {
return err // transient; safe to retry
}
return fmt.Errorf("cannot fetch channel member for user %s: %w", subscriberID, err)
} Defensive patterns
Strategy: validation
Validate before calling
// prune subscriptions pointing at deleted users before delivery runs
subs, err := appAPI.GetSubscribersForBlock(blockID)
if err != nil {
return err
}
for _, s := range subs {
if _, err := pd.api.GetUserByID(s.UserID); err != nil {
// remove or skip this subscription
}
} Type guard
func subscriberExists(api UserAPI, subscriberID string) bool {
_, err := api.GetUserByID(subscriberID)
return err == nil
} Try / catch
err := pd.SubscriptionDeliverSlackAttachments(evt, subscriptionType, subscriberID, extract)
if err != nil {
if model.IsErrNotFound(err) {
return nil // stale subscriber; drop
}
// transient API error: safe to retry
return retryDelivery(evt, subscriberID)
} Prevention
- Delete subscriptions when users are removed
- Distinguish not-found (skip) from transient errors (retry) using model.IsErrNotFound
- Monitor plugin API error rates during notification bursts
- Validate subscriber IDs when subscriptions are created
When it happens
Trigger: Delivering a slack-attachment style notification to a subscriber whose GetUserByID call fails for reasons other than ErrNotFound — plugin API unreachable, deactivated user treated as a hard error, transient server error, or invalid subscriber ID format.
Common situations: Mattermost server restarts while notification deliveries are queued; corrupted subscription records with stale user IDs; rate limiting or permission errors on the plugin API; partially deleted users (subscriptions not cleaned up).
Related errors
- cannot notify block subscribers for block %s: %w
- cannot find user: %w
- cannot get direct channel: %w
- cannot find user: %w
- mention not permitted
AI-assisted analysis of mattermost-community/focalboard@a84bbb65e3 (2026-08-30).
Data as JSON: /api/errors/86c8c7cdbaa99113.
Report an issue: GitHub.