I have a custom notification type, but getting a stack overflow exception when it triggers...

I have a custom notification type, but getting a stack overflow exception when it triggers...

Also ran it like this, with no exceptions, but nothing was actually created.
                                    _notificationController.CreateUpdate(new NotificationCreateUpdateOptions
                                    {
                                        ContentId = session.ContentId,
                                        ContentTypeId = session.ContentTypeId, 
                                        UserId = user.Id.Value,
                                        LastUpdate = DateTime.UtcNow
                                    });Also ran it like this, with no exceptions, but nothing was actually created.
                                    _notificationController.CreateUpdate(new NotificationCreateUpdateOptions
                                    {
                                        ContentId = session.ContentId,
                                        ContentTypeId = session.ContentTypeId, 
                                        UserId = user.Id.Value,
                                        LastUpdate = DateTime.UtcNow
                                    }); public class SessionPreLearningMissing : IPlugin, INotificationType, IRecurringEvolutionJobPlugin
    {
        #region Public Members
        public string SESSION_NOTIFICATIONS_FLAG = "RUN_SESSION_NOTIFICATIONS";
        #endregion
        #region Private Members
        private INotificationController _notificationController;
        #endregion
        #region IPlugin Members
        public string Name => "Hearing First - Session PreLearning Missing Notifications";
        public string Description => "Notification plugins for when the session is over, but learners still have pre-learning to complete";
        public void Initialize()
        {
           
        }
        #endregion
        #region INotificationType Plugin Members
        public string NotificationTypeName => "Session PreLearning Missing Notification Type";
        public string NotificationTypeDescription => "Notification type for missing pre-learning";
        public string NotificationTypeCategory => "Hearing First";
        public Guid NotificationTypeId => Guid.Parse("BC9C1D78-B680-42EE-A35F-0BC99B8B3F02");
        public bool IsCacheable => false;
        public bool VaryCacheByUser => false;
        public bool CanDeleteNotification(Guid notificationId, int userId)
        {
            return true;
        }
        public string GetMessage(Guid notificationId, [Documentation("Target", OptionsType = typeof(NotificationTarget))] string target)
        {
            var notification = Apis.Get<INotifications>().Get(notificationId);
            var session = HearingFirst.LearningExperience.Components.Sessions.Get(notification.ContentId.Value);
            var course = HearingFirst.LearningExperience.Components.Courses.Get(session.CourseId);
            switch (target)
            {
                case "Html":
                case "ShortText":
                case "Text":
                default: return String.Format("You have missing Session {0} pre-learning requirements in {1}", session.SortOrder.ToString(), course.Name);
            }
        }
        public string GetTargetUrl(Guid notificationId)
        {
            var notification = Apis.Get<INotifications>().Get(notificationId);
            var session = HearingFirst.LearningExperience.Components.Sessions.Get(notification.ContentId.Value);
            var course = HearingFirst.LearningExperience.Components.Courses.Get(session.CourseId);
            return course.Url;
        }
        public void SetController(INotificationController controller)
        {
            _notificationController = controller;
        }
        #endregion
        #region IRecurringEvolutionJobPlugin Members
        public Guid JobTypeId => Guid.Parse("636B5D02-809B-4AB1-8A63-01F2766B2BBB");
        public JobSchedule DefaultSchedule => JobSchedule.Daily();
        public JobContext SupportedContext => JobContext.Service;
        public void Execute(JobData jobData)
        {
            // Get all courses if open and datetime.now > startdate && less than close date + 5 days
            //Get the courses that arent finished yet
            var courses = HearingFirst.LearningExperience.Components.Courses.List();
            var activeCourses = (from c in courses where
                                 c.StartDate < DateTime.Now
                                 && c.EndDate.AddDays(5) > DateTime.Now select c).ToList();
            foreach(var course in activeCourses)
            {
                var registrants = HearingFirst.LearningExperience.Components.Courses.GetCourseRoster(course.GroupId);
                var sessions = HearingFirst.LearningExperience.Components.Sessions.ListCourseSessions(course.Id);
                
                // Loop through the sessions and determine if the session is flagged for notifications.
                foreach(var session in sessions)
                {
                    var flag = HearingFirst.ContentAttributes.Components.ContentAttributes.Get(session.ContentId, HearingFirst.LearningExperience.Components.Sessions.CONTENT_TYPE_ID, this.SESSION_NOTIFICATIONS_FLAG);
                    if(flag != null && flag.Value.Equals("1"))
                    {                        
                        foreach(var registrant in registrants)
                        {
                            try
                            {
                                var user = Apis.Get<IUsers>().Get(new UsersGetOptions { Username = registrant.Username });
                                var requirementsRemaining = Components.CourseRequirements.RemainingPreLearningSessionRequirementCount(user.Id.Value, course.Id, session.Id);
                                var adobeAttended = Components.CourseRequirements.TotalAdobeSessionRequirementsMet(user.Id.Value, course.Id, session.Id);
                                var totalAdobe = Components.CourseRequirements.TotalAdobeSessionRequirements(course.Id, session.Id);
                                if (requirementsRemaining > 0 && adobeAttended == totalAdobe)
                                {
                                    _notificationController.CreateUpdate(new NotificationCreateUpdateOptions
                                    {
                                        ContentId = session.ContentId,
                                        ContentTypeId = session.ContentTypeId, 
                                        UserId = user.Id.Value,
                                        LastUpdate = DateTime.UtcNow
                                    });
                                }
                            }
                            catch(Exception ex) {
                                var exc = ex;
                            }
                        }
                        
                        // Reset the session flag to "0" meaning the notifications have been sent for this session.
                        HearingFirst.ContentAttributes.Components.ContentAttributes.CreateOrUpdate(
                            new ContentAttributes.Entities.ContentAttribute {
                                ContentId = session.ContentId,
                                ContentTypeId = HearingFirst.LearningExperience.Components.Sessions.CONTENT_TYPE_ID,
                                Key = this.SESSION_NOTIFICATIONS_FLAG,
                                Value = "0",
                            });
                    }   
                }
            }
            
                    }
        #endregion
    }