@@ -855,26 +855,35 @@ export const createServer = Effect.fn(function* (): Effect.fn.Return<
855855
856856 let fileTreeDebounceTimer : ReturnType < typeof setTimeout > | null = null ;
857857
858- const fileTreeWatcher = fs . watch ( cwd , { recursive : true } , ( _eventType , filename ) => {
859- if ( ! filename ) return ;
860-
861- // Ignore changes inside noisy directories
862- const normalized = String ( filename ) . replaceAll ( "\\" , "/" ) ;
863- const firstSegment = normalized . split ( "/" ) [ 0 ] ;
864- if ( firstSegment && IGNORED_WATCHER_DIRS . has ( firstSegment ) ) return ;
865-
866- // Debounce rapid consecutive changes into a single push
867- if ( fileTreeDebounceTimer ) clearTimeout ( fileTreeDebounceTimer ) ;
868- fileTreeDebounceTimer = setTimeout ( ( ) => {
869- fileTreeDebounceTimer = null ;
870- clearWorkspaceIndexCache ( cwd ) ;
871- void Effect . runPromise ( pushBus . publishAll ( WS_CHANNELS . projectFileTreeChanged , { cwd } ) ) ;
872- } , FILE_TREE_DEBOUNCE_MS ) ;
858+ // fs.watch throws ENOENT when the directory does not exist (e.g. in tests
859+ // or when a workspace path has been removed). Guard against this so the
860+ // server can still start up.
861+ const fileTreeWatcher = yield * Effect . sync ( ( ) => {
862+ try {
863+ return fs . watch ( cwd , { recursive : true } , ( _eventType , filename ) => {
864+ if ( ! filename ) return ;
865+
866+ // Ignore changes inside noisy directories
867+ const normalized = String ( filename ) . replaceAll ( "\\" , "/" ) ;
868+ const firstSegment = normalized . split ( "/" ) [ 0 ] ;
869+ if ( firstSegment && IGNORED_WATCHER_DIRS . has ( firstSegment ) ) return ;
870+
871+ // Debounce rapid consecutive changes into a single push
872+ if ( fileTreeDebounceTimer ) clearTimeout ( fileTreeDebounceTimer ) ;
873+ fileTreeDebounceTimer = setTimeout ( ( ) => {
874+ fileTreeDebounceTimer = null ;
875+ clearWorkspaceIndexCache ( cwd ) ;
876+ void Effect . runPromise ( pushBus . publishAll ( WS_CHANNELS . projectFileTreeChanged , { cwd } ) ) ;
877+ } , FILE_TREE_DEBOUNCE_MS ) ;
878+ } ) ;
879+ } catch {
880+ return undefined ;
881+ }
873882 } ) ;
874883
875884 yield * Effect . addFinalizer ( ( ) =>
876885 Effect . sync ( ( ) => {
877- fileTreeWatcher . close ( ) ;
886+ fileTreeWatcher ? .close ( ) ;
878887 if ( fileTreeDebounceTimer ) clearTimeout ( fileTreeDebounceTimer ) ;
879888 } ) ,
880889 ) ;
0 commit comments