@@ -672,6 +672,15 @@ func (s *BM25Strategy) addPathToWatcher(ctx context.Context, path string) error
672672}
673673
674674func (s * BM25Strategy ) watchLoop (ctx context.Context , docPaths []string ) {
675+ // Capture watcher reference at goroutine start to avoid racing with Close()
676+ // which sets s.watcher = nil under watcherMu.
677+ s .watcherMu .Lock ()
678+ watcher := s .watcher
679+ s .watcherMu .Unlock ()
680+ if watcher == nil {
681+ return
682+ }
683+
675684 var debounceTimer * time.Timer
676685 debounceDuration := 2 * time .Second
677686 pendingChanges := make (map [string ]bool )
@@ -735,7 +744,7 @@ func (s *BM25Strategy) watchLoop(ctx context.Context, docPaths []string) {
735744 }
736745 return
737746
738- case event , ok := <- s . watcher .Events :
747+ case event , ok := <- watcher .Events :
739748 if ! ok {
740749 return
741750 }
@@ -746,7 +755,9 @@ func (s *BM25Strategy) watchLoop(ctx context.Context, docPaths []string) {
746755
747756 if event .Op & fsnotify .Create != 0 {
748757 s .watcherMu .Lock ()
749- _ = s .addPathToWatcher (ctx , event .Name )
758+ if s .watcher != nil {
759+ _ = s .addPathToWatcher (ctx , event .Name )
760+ }
750761 s .watcherMu .Unlock ()
751762 }
752763
@@ -769,7 +780,7 @@ func (s *BM25Strategy) watchLoop(ctx context.Context, docPaths []string) {
769780 }
770781 debounceTimer = time .AfterFunc (debounceDuration , processChanges )
771782
772- case err , ok := <- s . watcher .Errors :
783+ case err , ok := <- watcher .Errors :
773784 if ! ok {
774785 return
775786 }
0 commit comments