zed-industries/zed · error

failed to spawn fs watcher dispatch thread

Error message

failed to spawn fs watcher dispatch thread

What it means

A process-init guard for the global filesystem watcher: global_watcher() lazily spawns the single 'fs-watcher-dispatch' thread that drains watcher events, and .expect fires if the OS refuses to spawn it (thread/memory limits at startup). Because this runs inside a OnceLock initializer, the panic aborts whichever code first needed a file watcher (register_existing_path, ensure_*_watcher, poll_path_until_created, or even drop/remove) and the app cannot start watching files.

Source

Thrown at crates/fs/src/fs_watcher.rs:1124

});

pub fn poll_interval() -> Duration {
    *POLL_INTERVAL
}

static FS_WATCHER_INSTANCE: OnceLock<GlobalWatcher> = OnceLock::new();

fn global_watcher() -> &'static GlobalWatcher {
    FS_WATCHER_INSTANCE.get_or_init(|| {
        let (event_tx, event_rx) = async_channel::unbounded::<DispatchEvent>();
        std::thread::Builder::new()
            .name("fs-watcher-dispatch".to_owned())
            .spawn(move || {
                while let Ok(first) = event_rx.recv_blocking() {
                    global_watcher().dispatch_batch(first, &event_rx);
                }
            })
            .expect("failed to spawn fs watcher dispatch thread");
        GlobalWatcher {
            state: Mutex::new(WatcherState {
                watchers: Default::default(),
                native_path_registrations: Default::default(),
                poll_path_registrations: Default::default(),
                cooldown_until: None,
                last_registration: Default::default(),
            }),
            native_watcher: Mutex::new(None),
            poll_watcher: Mutex::new(None),
            event_tx,
        }
    })
}

#[cfg(test)]
mod tests {
    use super::*;

View on GitHub (pinned to f4178619ac)

Solutions

  1. Store the Result<GlobalWatcher, String> (or an ArcSwap Option) in the OnceLock so later callers can fall back to polling or report the failure
  2. Run the dispatch loop on an existing executor/background thread instead of a dedicated spawn
  3. Retry the thread spawn once with a smaller stack size before giving up
Defensive patterns

Strategy: fallback

When it happens

Trigger: Thrown at crates/fs/src/fs_watcher.rs:1124 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20). Data as JSON: /api/errors/27c3caf6c809143c. Report an issue: GitHub.