@@ -259,6 +259,14 @@ func (m *Monitor) checkThreadForSubscribers(
259259
260260 for email , sub := range info .subscribers {
261261 thread := sub .Threads [info .threadID ]
262+ if thread == nil {
263+ m .logger .Error ("CRITICAL: Thread not found in subscriber's thread map - data corruption or logic error" ,
264+ "cycle" , m .cycleNumber ,
265+ "email" , email ,
266+ "thread_id" , info .threadID ,
267+ "thread_url" , threadURL )
268+ continue
269+ }
262270
263271 m .logger .Info ("Processing subscriber" ,
264272 "cycle" , m .cycleNumber ,
@@ -272,7 +280,7 @@ func (m *Monitor) checkThreadForSubscribers(
272280
273281 // First check for this subscriber - just record the latest post ID
274282 if thread .LastPostID == "" {
275- if m .saveInitialState (ctx , sub , email , threadURL , latestPost .ID , savedEmails ) {
283+ if m .saveInitialState (ctx , sub , email , info . threadID , threadURL , latestPost .ID , savedEmails ) {
276284 hasUpdates = true
277285 }
278286 continue
@@ -286,7 +294,7 @@ func (m *Monitor) checkThreadForSubscribers(
286294 hasUpdates = true
287295 }
288296 } else {
289- m .saveStateNoNewPosts (ctx , sub , email , threadURL , savedEmails )
297+ m .saveStateNoNewPosts (ctx , sub , email , info . threadID , threadURL , savedEmails )
290298 }
291299 }
292300
@@ -326,6 +334,13 @@ func (m *Monitor) fetchThreadPosts(
326334 // Update thread title for all subscribers if not set
327335 for _ , sub := range info .subscribers {
328336 thread := sub .Threads [info .threadID ]
337+ if thread == nil {
338+ m .logger .Error ("CRITICAL: Thread not found when updating title - data corruption" ,
339+ "cycle" , m .cycleNumber ,
340+ "thread_id" , info .threadID ,
341+ "thread_url" , threadURL )
342+ continue
343+ }
329344 if thread .ThreadTitle == "" {
330345 thread .ThreadTitle = title
331346 }
@@ -353,9 +368,15 @@ func (m *Monitor) fetchThreadPosts(
353368}
354369
355370// updateLastPolledForAllSubscribers updates LastPolledAt for all subscribers when no posts are found.
356- func (* Monitor ) updateLastPolledForAllSubscribers (info * threadCheckInfo , now time.Time ) {
371+ func (m * Monitor ) updateLastPolledForAllSubscribers (info * threadCheckInfo , now time.Time ) {
357372 for _ , sub := range info .subscribers {
358373 thread := sub .Threads [info .threadID ]
374+ if thread == nil {
375+ m .logger .Error ("CRITICAL: Thread not found when updating poll time - data corruption" ,
376+ "cycle" , m .cycleNumber ,
377+ "thread_id" , info .threadID )
378+ continue
379+ }
359380 thread .LastPolledAt = now
360381 }
361382}
@@ -378,10 +399,18 @@ func (m *Monitor) updateSubscriberTimestamps(thread *notifier.Thread, now, lates
378399func (m * Monitor ) saveInitialState (
379400 ctx context.Context ,
380401 sub * notifier.Subscription ,
381- email , threadURL , postID string ,
402+ email , threadID , threadURL , postID string ,
382403 savedEmails map [string ]bool ,
383404) bool {
384- thread := sub .Threads [threadURL ]
405+ thread := sub .Threads [threadID ]
406+ if thread == nil {
407+ m .logger .Error ("CRITICAL: Thread not found when saving initial state - data corruption" ,
408+ "cycle" , m .cycleNumber ,
409+ "email" , email ,
410+ "thread_id" , threadID ,
411+ "thread_url" , threadURL )
412+ return false
413+ }
385414 thread .LastPostID = postID
386415
387416 m .logger .Info ("Saving initial state for subscriber" ,
@@ -515,8 +544,16 @@ func (m *Monitor) sendNotificationAndSave(ctx context.Context, sub *notifier.Sub
515544}
516545
517546// saveStateNoNewPosts saves state when there are no new posts for a subscriber.
518- func (m * Monitor ) saveStateNoNewPosts (ctx context.Context , sub * notifier.Subscription , email , threadURL string , savedEmails map [string ]bool ) {
519- thread := sub .Threads [threadURL ]
547+ func (m * Monitor ) saveStateNoNewPosts (ctx context.Context , sub * notifier.Subscription , email , threadID , threadURL string , savedEmails map [string ]bool ) {
548+ thread := sub .Threads [threadID ]
549+ if thread == nil {
550+ m .logger .Error ("CRITICAL: Thread not found when saving state (no new posts) - data corruption" ,
551+ "cycle" , m .cycleNumber ,
552+ "email" , email ,
553+ "thread_id" , threadID ,
554+ "thread_url" , threadURL )
555+ return
556+ }
520557
521558 m .logger .Info ("No new posts - saving state" ,
522559 "cycle" , m .cycleNumber ,
0 commit comments