zed-industries/zed · error
native watcher initialized
Error message
native watcher initialized
What it means
A post-condition guard in the native watch path: ensure_native_watcher() was just called successfully, so the native_watcher field behind the mutex is expected to be Some. The expect fires only if that invariant is broken — ensure_native_watcher succeeded without installing the watcher (a logic contradiction) or another thread tore the watcher down between the two calls. It is an internal consistency check, not an input-driven error.
Source
Thrown at crates/fs/src/fs_watcher.rs:1000
}
pub fn remove(&self, id: WatcherRegistrationId) {
let mut state = self.state.lock();
let Some((path, mode)) = state.remove_registration(id) else {
return;
};
drop(state);
self.unwatch(path.as_path(), mode).log_err();
}
fn watch(&self, path: &Path, mode: WatcherMode) -> anyhow::Result<()> {
match mode {
WatcherMode::Native => {
self.ensure_native_watcher()?;
self.native_watcher
.lock()
.as_mut()
.expect("native watcher initialized")
.watch(
path,
if cfg!(any(target_os = "windows", target_os = "macos")) {
notify::RecursiveMode::Recursive
} else {
notify::RecursiveMode::NonRecursive
},
)?;
}
WatcherMode::Poll => {
self.ensure_poll_watcher()?;
self.poll_watcher
.lock()
.as_mut()
.expect("poll watcher initialized")
.watch(path, notify::RecursiveMode::Recursive)?;
}
}View on GitHub (pinned to f4178619ac)
Solutions
- Have ensure_native_watcher return the &mut watcher it guaranteed, removing the second lock+expect
- Treat None as a retryable state: re-run ensure_native_watcher and try again instead of panicking
- Hold the same lock across ensure + use so teardown cannot interleave
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at crates/fs/src/fs_watcher.rs:1000 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/b182bdc5b38be7a4.
Report an issue: GitHub.