mattermost-community/focalboard · error
cannot get direct channel: %w
Error message
cannot get direct channel: %w
What it means
getDirectChannelID wraps the failure of pd.getDirectChannel when resolving the direct-message channel between a subscriber and the delivery bot. Note the bug-prone shape: if getDirectChannel returns (nil, nil) — a nil channel with no error — the %w wraps a nil err, producing an error with a trailing empty cause. It means either the bot could not be added to the team or the direct channel could not be found/created in Mattermost.
Source
Thrown at server/services/notify/plugindelivery/subscription_deliver.go:57
ChannelId: channelID,
}
mm_model.ParseSlackAttachment(post, attachments)
_, err = pd.api.CreatePost(post)
return err
}
func (pd *PluginDelivery) getDirectChannelID(teamID string, subscriberID string, subscriberType model.SubscriberType, botID string) (string, error) {
switch subscriberType {
case model.SubTypeUser:
user, err := pd.api.GetUserByID(subscriberID)
if err != nil {
return "", fmt.Errorf("cannot find user: %w", err)
}
channel, err := pd.getDirectChannel(teamID, user.Id, botID)
if err != nil || channel == nil {
return "", fmt.Errorf("cannot get direct channel: %w", err)
}
return channel.Id, nil
case model.SubTypeChannel:
return subscriberID, nil
default:
return "", ErrUnsupportedSubscriberType
}
}
func (pd *PluginDelivery) getDirectChannel(teamID string, userID string, botID string) (*mm_model.Channel, error) {
// first ensure the bot is a member of the team.
_, err := pd.api.CreateMember(teamID, botID)
if err != nil {
return nil, fmt.Errorf("cannot add bot to team %s: %w", teamID, err)
}
return pd.api.GetDirectChannelOrCreate(userID, botID)
}
View on GitHub (pinned to a84bbb65e3)
Solutions
- Verify the bot account exists, is active, and has permission to be added as a team member.
- Check the subscriber record points to a valid Mattermost user ID in the target team.
- Inspect the wrapped cause (%w) from the Mattermost API logs to see whether CreateMember or GetDirectChannelOrCreate failed.
- Fix the nil-channel nil-error case by returning an explicit error when channel == nil instead of wrapping a nil err.
Example fix
// before
channel, err := pd.getDirectChannel(teamID, user.Id, botID)
if err != nil || channel == nil {
return "", fmt.Errorf("cannot get direct channel: %w", err)
}
// after
channel, err := pd.getDirectChannel(teamID, user.Id, botID)
if err != nil {
return "", fmt.Errorf("cannot get direct channel: %w", err)
}
if channel == nil {
return "", fmt.Errorf("cannot get direct channel for user %s: channel is nil", user.Id)
} Defensive patterns
Strategy: try-catch
Validate before calling
// before delivering, verify subscriber user exists (plugin API)
u, err := api.GetUserByID(subscriberID)
if err != nil || u == nil || u.DeleteAt != 0 {
// skip/queue this subscriber instead of attempting delivery
} Type guard
func validChannel(c *mm_model.Channel) bool { return c != nil && c.Id != "" } Try / catch
chID, err := getDirectChannelID(teamID, subscriberID, botID)
if err != nil {
var nilCh *NilChannelError
if errors.As(err, &nilCh) || strings.Contains(err.Error(), "cannot get direct channel") {
logger.Warn("skipping DM subscriber", "subscriber", subscriberID, "cause", err)
return // degrade gracefully, don't fail whole delivery
}
return err
} Prevention
- Keep the bot active and a member of all teams with subscriptions.
- Treat nil-channel/nil-error explicitly instead of wrapping a nil err.
- Monitor Mattermost API errors in plugin logs for CreateMember/GetDirectChannelOrCreate.
When it happens
Trigger: SubscriptionDeliverSlackAttachments resolves a subscriber of type DirectMessage; pd.api.CreateMember(teamID, botID) fails, or pd.api.GetDirectChannelOrCreate(userID, botID) fails, or returns nil channel with nil error.
Common situations: Bot user is deleted or deactivated; bot lacks permission to join the team; subscriber ID refers to a stale/deleted user (though that fails earlier with 'cannot find user'); Mattermost API connectivity/permission problems in the plugin.
Related errors
AI-assisted analysis of mattermost-community/focalboard@a84bbb65e3 (2026-08-30).
Data as JSON: /api/errors/ac2a5035146b0705.
Report an issue: GitHub.