mattermost-community/focalboard · error

cannot add bot to team %s: %w

Error message

cannot add bot to team %s: %w

What it means

getDirectChannel first ensures the delivery bot is a member of the team by calling pd.api.CreateMember(teamID, botID); when that call fails the error is wrapped as 'cannot add bot to team %s'. The subsequent direct channel creation never runs. This is a permission/team-membership failure at the Mattermost API level.

Source

Thrown at server/services/notify/plugindelivery/subscription_deliver.go:71

			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

  1. Confirm the bot user exists and is active, and that teamID is a valid team ID.
  2. Manually add the bot to the team or grant it the needed permissions so CreateMember succeeds idempotently.
  3. Check the plugin's bot access token configuration in Mattermost system console.
  4. Log/inspect the wrapped cause to distinguish 'already a member' from permission failures.
Defensive patterns

Strategy: validation

Validate before calling

// before delivery, check bot membership
bot, err := api.GetUser(botID)
if err != nil || bot.DeleteAt != 0 {
	return fmt.Errorf("bot %s missing or deactivated", botID)
}
tm, _ := api.GetTeamMember(teamID, botID)
if tm == nil {
	_, err = api.CreateMember(teamID, botID) // pre-provision
	if err != nil {
		return fmt.Errorf("pre-provision bot into team %s failed: %w", teamID, err)
	}
}

Try / catch

chID, err := deliverer.SubscriptionDeliverSlackAttachments(...)
if err != nil && strings.Contains(err.Error(), "cannot add bot to team") {
	logger.Error("bot cannot join team; check bot config/permissions", "team", teamID, "err", err)
	return // alert operator rather than retrying blindly
}

Prevention

When it happens

Trigger: Called from getDirectChannelID (DM subscriptions) or MentionDeliver; pd.api.CreateMember(teamID, botID) returns an error — the bot is already a member but the API errors, the bot is not allowed to join, teamID is invalid, or the bot account is deactivated.

Common situations: Bot not invited/configured for the team; bot token lacking 'join_team' permissions; team ID typo or team deleted; Mattermost plugin misconfiguration (bot access token pointing at the wrong bot); Mattermost version differences in CreateMember semantics.

Related errors


AI-assisted analysis of mattermost-community/focalboard@a84bbb65e3 (2026-08-30). Data as JSON: /api/errors/f6d8717cc40f1f22. Report an issue: GitHub.