{"record":{"id":"f04c1437f0f8f9d6","repo":"spacedriveapp/spacedrive","slug":"ephemeraleventhandler-not-connected-to-fswatcherse","errorCode":null,"errorMessage":"EphemeralEventHandler not connected to FsWatcherService","messagePattern":"EphemeralEventHandler not connected to FsWatcherService","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/src/ops/indexing/handlers/ephemeral.rs","lineNumber":79,"sourceCode":"\n\t/// Connect to a FsWatcherService\n\tpub async fn connect(&self, fs_watcher: Arc<FsWatcherService>) {\n\t\t*self.fs_watcher.write().await = Some(fs_watcher);\n\t}\n\n\t/// Start the event handler\n\t///\n\t/// Spawns a task that subscribes to filesystem events and routes\n\t/// matching events to the ephemeral responder.\n\tpub async fn start(&self) -> Result<()> {\n\t\tif self.is_running.swap(true, Ordering::SeqCst) {\n\t\t\twarn!(\"EphemeralEventHandler is already running\");\n\t\t\treturn Ok(());\n\t\t}\n\n\t\tlet fs_watcher = self.fs_watcher.read().await.clone();\n\t\tlet Some(fs_watcher) = fs_watcher else {\n\t\t\treturn Err(anyhow::anyhow!(\n\t\t\t\t\"EphemeralEventHandler not connected to FsWatcherService\"\n\t\t\t));\n\t\t};\n\n\t\tdebug!(\"Starting EphemeralEventHandler\");\n\n\t\tlet mut rx = fs_watcher.subscribe();\n\t\tlet context = self.context.clone();\n\t\tlet rule_toggles = self.rule_toggles;\n\t\tlet is_running = self.is_running.clone();\n\n\t\ttokio::spawn(async move {\n\t\t\tdebug!(\"EphemeralEventHandler task started\");\n\n\t\t\twhile is_running.load(Ordering::SeqCst) {\n\t\t\t\tmatch rx.recv().await {\n\t\t\t\t\tOk(event) => {\n\t\t\t\t\t\tif let Err(e) = Self::handle_event(&context, &event, rule_toggles).await {","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/spacedriveapp/spacedrive/blob/6dfeccf2113039e35f2ce735f945e70dc3e4ea45/core/src/ops/indexing/handlers/ephemeral.rs#L61-L97","documentation":"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.","triggerScenarios":"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.","commonSituations":"Wiring order bugs in daemon startup (start before connect); test harnesses building the handler without a real watcher; watcher service disabled in configuration.","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"],"exampleFix":"// before\nlet Some(fs_watcher) = fs_watcher else {\n    return Err(anyhow::anyhow!(\"EphemeralEventHandler not connected to FsWatcherService\"));\n};\n\n// after: fail fast at wiring time, not at start time\nlet Some(fs_watcher) = fs_watcher else {\n    warn!(\"EphemeralEventHandler start skipped: no FsWatcherService connected\");\n    return Ok(());\n};","handlingStrategy":"validation","validationCode":"// Verify wiring before starting\nif self.fs_watcher.read().await.is_none() {\n    tracing::warn!(\"EphemeralEventHandler has no FsWatcherService; not starting\");\n    return Ok(());\n}\nself.start().await?;","typeGuard":null,"tryCatchPattern":"if let Err(e) = handler.start().await {\n    if e.to_string().contains(\"not connected to FsWatcherService\") {\n        // fix wiring order: connect watcher first, then call start() again\n    }\n}","preventionTips":["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()"],"tags":["ephemeral-index","watcher","lifecycle","wiring","indexing"],"backgroundTag":null,"analyzedSha":"6dfeccf2113039e35f2ce735f945e70dc3e4ea45","analyzedAt":"2026-08-16T11:26:17.074Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}