{"record":{"id":"d3a46dad7277b6b7","repo":"mattermost-community/focalboard","slug":"invalid-subscriber-type","errorCode":null,"errorMessage":"invalid subscriber type","messagePattern":"invalid subscriber type","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/services/notify/plugindelivery/subscription_deliver.go","lineNumber":16,"sourceCode":"// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n// See LICENSE.txt for license information.\n\npackage plugindelivery\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/mattermost/focalboard/server/model\"\n\n\tmm_model \"github.com/mattermost/mattermost/server/public/model\"\n)\n\nvar (\n\tErrUnsupportedSubscriberType = errors.New(\"invalid subscriber type\")\n)\n\n// SubscriptionDeliverSlashAttachments notifies a user that changes were made to a block they are subscribed to.\nfunc (pd *PluginDelivery) SubscriptionDeliverSlackAttachments(teamID string, subscriberID string, subscriptionType model.SubscriberType,\n\tattachments []*mm_model.SlackAttachment) error {\n\t// check subscriber is member of channel\n\t_, err := pd.api.GetUserByID(subscriberID)\n\tif err != nil {\n\t\tif model.IsErrNotFound(err) {\n\t\t\t// subscriber is not a member of the channel; fail silently.\n\t\t\treturn nil\n\t\t}\n\t\treturn fmt.Errorf(\"cannot fetch channel member for user %s: %w\", subscriberID, err)\n\t}\n\n\tchannelID, err := pd.getDirectChannelID(teamID, subscriberID, subscriptionType, pd.botID)\n\tif err != nil {\n\t\treturn err","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/mattermost-community/focalboard/blob/a84bbb65e32edf972856b329417096ac413518e9/server/services/notify/plugindelivery/subscription_deliver.go#L1-L34","documentation":"ErrUnsupportedSubscriberType means a subscription's subscriber type is not one the delivery mechanism can resolve to a destination. getDirectChannelID returns it when the subscriber is not a user/channel type it knows, so plugin delivery cannot determine where to send the notification. It acts as a type guard in the subscription delivery path.","triggerScenarios":"Calling SubscriptionDeliver*/getDirectChannelID with a model.SubscriberType other than the supported kinds (e.g. a bare user type where a channel id is required, or a newly introduced subscriber type not yet handled by the plugin delivery code).","commonSituations":"Subscriptions persisted by a newer Focalboard version read by older delivery code, custom plugins creating subscription rows with unexpected types, or data corruption in the subscriptions table.","solutions":["Verify the subscription's SubscriberType is one supported by plugin delivery (channel/user types that map to a Mattermost channel).","Delete or correct the malformed subscription row so notifications target a valid channel.","Align Focalboard plugin and server versions so all subscriber types are understood.","Switch errors.Is(err, ErrUnsupportedSubscriberType) to skip that subscription rather than failing the batch."],"exampleFix":"// before\nerr := pd.SubscriptionDeliverSlackAttachments(teamID, subID, subscriberType, attachments)\n// after\nif err := pd.SubscriptionDeliverSlackAttachments(teamID, subID, subscriberType, attachments); err != nil {\n    if errors.Is(err, plugindelivery.ErrUnsupportedSubscriberType) {\n        return nil // skip unsupported subscription\n    }\n    return err\n}","handlingStrategy":"type-guard","validationCode":"switch subscriberType {\ncase model.SubscriberTypeUser, model.SubscriberTypeChannel:\n    // supported\ndefault:\n    return fmt.Errorf(\"unsupported subscriber type %q\", subscriberType)\n}","typeGuard":"func isDeliverableSubscriberType(t model.SubscriberType) bool {\n    return t == model.SubscriberTypeUser || t == model.SubscriberTypeChannel\n}","tryCatchPattern":"if err := pd.SubscriptionDeliverSlackAttachments(teamID, subID, subType, attachments); err != nil {\n    if errors.Is(err, ErrUnsupportedSubscriberType) {\n        return nil // skip: no channel destination for this type\n    }\n    return err\n}","preventionTips":["Only create subscriptions with subscriber types supported by your delivery plugin.","Keep server and plugin versions aligned.","Validate SubscriberType before persisting subscription rows."],"tags":["go","notifications","type-guard"],"backgroundTag":"unsupported-subscriber-type","analyzedSha":"a84bbb65e32edf972856b329417096ac413518e9","analyzedAt":"2026-08-30T09:22:20.720Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}