{"record":{"id":"27c3caf6c809143c","repo":"zed-industries/zed","slug":"failed-to-spawn-fs-watcher-dispatch-thread","errorCode":null,"errorMessage":"failed to spawn fs watcher dispatch thread","messagePattern":"failed to spawn fs watcher dispatch thread","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fs/src/fs_watcher.rs","lineNumber":1124,"sourceCode":"});\n\npub fn poll_interval() -> Duration {\n    *POLL_INTERVAL\n}\n\nstatic FS_WATCHER_INSTANCE: OnceLock<GlobalWatcher> = OnceLock::new();\n\nfn global_watcher() -> &'static GlobalWatcher {\n    FS_WATCHER_INSTANCE.get_or_init(|| {\n        let (event_tx, event_rx) = async_channel::unbounded::<DispatchEvent>();\n        std::thread::Builder::new()\n            .name(\"fs-watcher-dispatch\".to_owned())\n            .spawn(move || {\n                while let Ok(first) = event_rx.recv_blocking() {\n                    global_watcher().dispatch_batch(first, &event_rx);\n                }\n            })\n            .expect(\"failed to spawn fs watcher dispatch thread\");\n        GlobalWatcher {\n            state: Mutex::new(WatcherState {\n                watchers: Default::default(),\n                native_path_registrations: Default::default(),\n                poll_path_registrations: Default::default(),\n                cooldown_until: None,\n                last_registration: Default::default(),\n            }),\n            native_watcher: Mutex::new(None),\n            poll_watcher: Mutex::new(None),\n            event_tx,\n        }\n    })\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;","sourceCodeStart":1106,"sourceCodeEnd":1142,"githubUrl":"https://github.com/zed-industries/zed/blob/f4178619acd0d47ea1f76a2025c42962c6d6638c/crates/fs/src/fs_watcher.rs#L1106-L1142","documentation":"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.","triggerScenarios":"Thrown at crates/fs/src/fs_watcher.rs:1124 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Store the Result<GlobalWatcher, String> (or an ArcSwap Option) in the OnceLock so later callers can fall back to polling or report the failure","Run the dispatch loop on an existing executor/background thread instead of a dedicated spawn","Retry the thread spawn once with a smaller stack size before giving up"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"f4178619acd0d47ea1f76a2025c42962c6d6638c","analyzedAt":"2026-08-20T19:29:52.058Z","contentChangedAt":"2026-08-20T19:29:52.058Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}