{"record":{"id":"036ae4f50beab64e","repo":"mattermost-community/focalboard","slug":"mention-not-permitted","errorCode":null,"errorMessage":"mention not permitted","messagePattern":"mention not permitted","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"info","filePath":"server/services/notify/notifymentions/mentions_backend.go","lineNumber":24,"sourceCode":"import (\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n\n\t\"github.com/mattermost/focalboard/server/model\"\n\t\"github.com/mattermost/focalboard/server/services/notify\"\n\t\"github.com/mattermost/focalboard/server/services/permissions\"\n\t\"github.com/wiggin77/merror\"\n\n\t\"github.com/mattermost/mattermost/server/public/shared/mlog\"\n)\n\nconst (\n\tbackendName = \"notifyMentions\"\n)\n\nvar (\n\tErrMentionPermission = errors.New(\"mention not permitted\")\n)\n\ntype MentionListener interface {\n\tOnMention(userID string, evt notify.BlockChangeEvent)\n}\n\ntype BackendParams struct {\n\tAppAPI      AppAPI\n\tPermissions permissions.PermissionsService\n\tDelivery    MentionDelivery\n\tLogger      mlog.LoggerIFace\n}\n\n// Backend provides the notification backend for @mentions.\ntype Backend struct {\n\tappAPI      AppAPI\n\tpermissions permissions.PermissionsService\n\tdelivery    MentionDelivery","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/mattermost-community/focalboard/blob/a84bbb65e32edf972856b329417096ac413518e9/server/services/notify/notifymentions/mentions_backend.go#L6-L42","documentation":"ErrMentionPermission is the notifyMentions backend's sentinel for a mention that policy does not allow to be delivered. deliverMentionNotification returns it when the modifying user is unknown, is a viewer, or lacks permission to mention the target (non-team member on open boards, non-board member on private boards). BlockChanged intentionally logs and swallows it as a normal, expected outcome rather than an error.","triggerScenarios":"A block change contains an @username mention where: evt.ModifiedBy is nil; the modifier is a board viewer; an open-board editor/admin mentions a user who cannot view the team; or any board member mentions a user without PermissionViewBoard on a private board.","commonSituations":"Guests typing @mentions of users outside their board, viewers attempting mentions, mentions of deactivated/external users, and plugin tests simulating mention events with incomplete ModifiedBy data.","solutions":["Ensure the mentioning user has the required role (at least commenter/editor on open boards; board membership for guests/private boards).","Only mention users who are team members (open boards) or board members (private boards).","Treat the error as informational: use errors.Is(err, ErrMentionPermission) to log-and-continue exactly as BlockChanged does.","Include valid ModifiedBy user data in the BlockChangeEvent; nil ModifiedBy always yields this error."],"exampleFix":"// before: treating every delivery failure as fatal\nif err := backend.BlockChanged(evt); err != nil { return err }\n// after\nif err := backend.BlockChanged(evt); err != nil && !errors.Is(err, notifymentions.ErrMentionPermission) {\n    return err\n}","handlingStrategy":"try-catch","validationCode":"// before triggering notification, verify modifier and target\nif evt.ModifiedBy == nil {\n    return // no valid modifier: mention cannot be permitted\n}\nhasView, _ := permissions.HasPermissionToBoard(mentionedUser.Id, evt.Board.ID, model.PermissionViewBoard)\nif evt.Board.Type != model.BoardTypeOpen && !hasView {\n    return // would be rejected with ErrMentionPermission\n}","typeGuard":"func canMention(modifier *model.User, board *model.Board) bool {\n    return modifier != nil &&\n        !modifier.SchemeViewer\n}","tryCatchPattern":"_, err := backend.BlockChanged(evt) // via BlockChanged flow\nif errors.Is(err, ErrMentionPermission) {\n    logger.Debug(\"mention not permitted; skipping\", \"user\", username)\n    return nil // expected condition, not a failure\n}","preventionTips":["Only mention users who are team members (open boards) or board members (private boards).","Ensure mention events carry a non-nil ModifiedBy user.","Viewers and guests should not attempt cross-board mentions.","Always errors.Is-check this sentinel and treat it as informational."],"tags":["go","permissions","notifications"],"backgroundTag":"permission-denied","analyzedSha":"a84bbb65e32edf972856b329417096ac413518e9","analyzedAt":"2026-08-30T09:22:20.720Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}