{"record":{"id":"659f75cd99d02aee","repo":"mattermost-community/focalboard","slug":"cannot-find-user-w-659f75","errorCode":null,"errorMessage":"cannot find user: %w","messagePattern":"cannot find user: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/services/notify/plugindelivery/subscription_deliver.go","lineNumber":53,"sourceCode":"\t}\n\n\tpost := &mm_model.Post{\n\t\tUserId:    pd.botID,\n\t\tChannelId: channelID,\n\t}\n\n\tmm_model.ParseSlackAttachment(post, attachments)\n\n\t_, err = pd.api.CreatePost(post)\n\treturn err\n}\n\nfunc (pd *PluginDelivery) getDirectChannelID(teamID string, subscriberID string, subscriberType model.SubscriberType, botID string) (string, error) {\n\tswitch subscriberType {\n\tcase model.SubTypeUser:\n\t\tuser, err := pd.api.GetUserByID(subscriberID)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"cannot find user: %w\", err)\n\t\t}\n\t\tchannel, err := pd.getDirectChannel(teamID, user.Id, botID)\n\t\tif err != nil || channel == nil {\n\t\t\treturn \"\", fmt.Errorf(\"cannot get direct channel: %w\", err)\n\t\t}\n\t\treturn channel.Id, nil\n\tcase model.SubTypeChannel:\n\t\treturn subscriberID, nil\n\tdefault:\n\t\treturn \"\", ErrUnsupportedSubscriberType\n\t}\n}\n\nfunc (pd *PluginDelivery) getDirectChannel(teamID string, userID string, botID string) (*mm_model.Channel, error) {\n\t// first ensure the bot is a member of the team.\n\t_, err := pd.api.CreateMember(teamID, botID)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot add bot to team %s: %w\", teamID, err)","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/mattermost-community/focalboard/blob/a84bbb65e32edf972856b329417096ac413518e9/server/services/notify/plugindelivery/subscription_deliver.go#L35-L71","documentation":"getDirectChannelID returns this error when GetUserByID fails while resolving a 'user'-type subscriber's direct channel for subscription delivery. The subscriber's user record cannot be fetched from the Mattermost plugin API, so no DM channel can be opened. The underlying error is wrapped with %w and propagates to SubscriptionDeliverSlackAttachments.","triggerScenarios":"SubscriptionDeliverSlackAttachments processes a subscriber with model.SubTypeUser and GetUserByID(subscriberID) fails — deleted or deactivated subscriber, stale subscription record, plugin API error, or invalid user ID.","commonSituations":"Subscriptions left behind after user deletion; SSO/LDAP deprovisioning removing users that still have board subscriptions; plugin API outages during notification bursts; instance restores with inconsistent user data.","solutions":["Verify the subscriber user exists and is active via GetUserByID","Prune subscriptions whose users no longer exist","Check plugin API health and bot permissions","Handle the wrapped not-found cause gracefully (skip delivery) as done for channel-member checks"],"exampleFix":"// before\nuser, err := pd.api.GetUserByID(subscriberID)\nif err != nil {\n\treturn \"\", fmt.Errorf(\"cannot find user: %w\", err)\n}\n// after\nuser, err := pd.api.GetUserByID(subscriberID)\nif err != nil {\n\tif model.IsErrNotFound(err) {\n\t\treturn \"\", nil // subscriber deleted; drop silently\n\t}\n\treturn \"\", fmt.Errorf(\"cannot find user: %w\", err)\n}","handlingStrategy":"validation","validationCode":"user, err := pd.api.GetUserByID(subscriberID)\nif err != nil {\n\t// user gone: remove subscription instead of attempting delivery\n\t_ = removeSubscription(subscriberID)\n\treturn\n}","typeGuard":"func validUserSubscriber(api UserAPI, id string) bool {\n\tu, err := api.GetUserByID(id)\n\treturn err == nil && u.DeleteAt == 0\n}","tryCatchPattern":"err := pd.SubscriptionDeliverSlackAttachments(evt, subscriptionType, subscriberID, extract)\nif err != nil {\n\tif model.IsErrNotFound(err) {\n\t\treturn nil // subscriber deleted; skip\n\t}\n\treturn err\n}","preventionTips":["Cascade-delete subscriptions when a user account is deleted","Treat not-found subscriber lookups as skip-and-clean, not hard errors","Verify user type subscribers are active before opening DM channels","Check plugin API health before batch notification delivery"],"tags":["go","mattermost-plugin","subscriptions","user-lookup"],"backgroundTag":"user-lookup-failed","analyzedSha":"a84bbb65e32edf972856b329417096ac413518e9","analyzedAt":"2026-08-30T09:22:20.720Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}