spacedriveapp/spacedrive · error
EphemeralEventHandler not connected to FsWatcherService
Error message
EphemeralEventHandler not connected to FsWatcherService
What it means
EphemeralEventHandler::start guards against double-start with an atomic flag, then clones the FsWatcherService from an RwLock<Option<...>>. If that slot is None, the handler has no event bus to subscribe to and start() returns this error: the handler was constructed without (or before) being connected to the watcher service.
Source
Thrown at core/src/ops/indexing/handlers/ephemeral.rs:79
/// Connect to a FsWatcherService
pub async fn connect(&self, fs_watcher: Arc<FsWatcherService>) {
*self.fs_watcher.write().await = Some(fs_watcher);
}
/// Start the event handler
///
/// Spawns a task that subscribes to filesystem events and routes
/// matching events to the ephemeral responder.
pub async fn start(&self) -> Result<()> {
if self.is_running.swap(true, Ordering::SeqCst) {
warn!("EphemeralEventHandler is already running");
return Ok(());
}
let fs_watcher = self.fs_watcher.read().await.clone();
let Some(fs_watcher) = fs_watcher else {
return Err(anyhow::anyhow!(
"EphemeralEventHandler not connected to FsWatcherService"
));
};
debug!("Starting EphemeralEventHandler");
let mut rx = fs_watcher.subscribe();
let context = self.context.clone();
let rule_toggles = self.rule_toggles;
let is_running = self.is_running.clone();
tokio::spawn(async move {
debug!("EphemeralEventHandler task started");
while is_running.load(Ordering::SeqCst) {
match rx.recv().await {
Ok(event) => {
if let Err(e) = Self::handle_event(&context, &event, rule_toggles).await {View on GitHub (pinned to 6dfeccf211)
Solutions
- Connect the FsWatcherService to the handler before calling start()
- Make daemon startup order explicit: construct watcher → attach handlers → start handlers
- If running without a watcher is legitimate for your deployment, return Ok(()) with a warn instead of erroring
Example fix
// before
let Some(fs_watcher) = fs_watcher else {
return Err(anyhow::anyhow!("EphemeralEventHandler not connected to FsWatcherService"));
};
// after: fail fast at wiring time, not at start time
let Some(fs_watcher) = fs_watcher else {
warn!("EphemeralEventHandler start skipped: no FsWatcherService connected");
return Ok(());
}; Defensive patterns
Strategy: validation
Validate before calling
// Verify wiring before starting
if self.fs_watcher.read().await.is_none() {
tracing::warn!("EphemeralEventHandler has no FsWatcherService; not starting");
return Ok(());
}
self.start().await?; Try / catch
if let Err(e) = handler.start().await {
if e.to_string().contains("not connected to FsWatcherService") {
// fix wiring order: connect watcher first, then call start() again
}
} Prevention
- Make daemon startup order explicit: create watcher → attach to handlers → start handlers
- Fail watcher construction loudly so a None slot is never silently carried
- In tests, always install a real or mock FsWatcherService before start()
When it happens
Trigger: Calling start() before a FsWatcherService was set via the handler's connect/setter; watcher construction failed earlier and the None placeholder remained; start() invoked during daemon teardown after the watcher was taken out.
Common situations: Wiring order bugs in daemon startup (start before connect); test harnesses building the handler without a real watcher; watcher service disabled in configuration.
Related errors
- PersistentEventHandler not connected to FsWatcherService
- Failed to add entry to ephemeral index: {}
- Library not found: {}
- Location not found: {}
- Arena index mismatch: expected {}, got {}
AI-assisted analysis of spacedriveapp/spacedrive@6dfeccf211 (2026-08-16).
Data as JSON: /api/errors/f04c1437f0f8f9d6.
Report an issue: GitHub.