The invisible subsystem finally gets gauges.
Zed’s 1.20.1 preview adds dev: Debug Filesystem Watching. The window captures native and polling notifications before filtering and coalescing; separates raw events, watch roots, and scan exclusions; records lost-sync markers and registration errors; and exports a JSON capture with dropped-event counts plus editor and OS versions.[1]
The implementation is unusually honest about scope. It records only while the window is open, retains the latest 10,000 events, periodically compacts its editor buffers, and does not yet trace remote filesystems or worktree scan completion.[2] That is not a universal black box. It is a bounded flight recorder.
“Restart it” clears the smoke. A capture tells you which wire burned.
Capacity and causality are different repairs.
The same Zed preview raises the soft open-file limit early at startup on Unix and macOS. Its pull request says active workspaces with language servers, context servers, filesystem watchers, and agent tool calls can sit near the low GUI-inherited macOS limit before bursts push the process into EMFILE.[3]
That is sensible headroom, not absolution. More descriptors can stop a premature failure. They do not explain duplicate watches, rescan storms, exclusions that do not mean event suppression, or an event queue that lost sync. Capacity keeps the engine running; diagnostics keep you from tuning by superstition.
The operating system never promised a perfect story.
Linux’s inotify documentation says robust applications should expect monitoring races to leave a cache inconsistent and should perform consistency checks or rebuild the cache. It also notes that monitoring is not recursive, remote network events are not caught, names may be gone by the time an event is processed, and queue overflow requires recovery.[4]
Node’s fs.watch() documentation adds portable sharp edges: watching can be unreliable on network and virtualized filesystems, a deleted-and-recreated path can leave the watcher attached to the old inode on Linux and macOS, and the callback filename is not guaranteed.[5]
Build the debug surface before the next stale tree.
A useful watcher dashboard needs four planes. Raw events show what arrived. Roots show what was registered. Exclusions explain scanner policy without pretending the OS stopped emitting. Loss and recovery record overflow, dropped events, rescans, and the moment cached state became trustworthy again.
Then bind the capture to a reproduction: editor version, OS, workspace shape, local or remote filesystem, the save operation, expected state, observed stale state, and an exportable event slice. If the report cannot survive outside the reporter’s machine, it is still a ghost story.