From 452fbf46d70d9cae63f313edf093ed5bca6e6d07 Mon Sep 17 00:00:00 2001 From: James Pine Date: Fri, 17 Apr 2026 18:25:48 -0700 Subject: [PATCH] self-heal protocol handler registration on re-init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Core::new() registers default protocol handlers after starting networking, but swallows any failure (error is only logged). If the initial registration fails — e.g. on a host where start_networking hasn't fully set up the event loop command sender by the time register_default_protocol_handlers runs — the registry is left empty. A subsequent call to Core::init_networking() would see `services.networking().is_some()` and skip re-registration, permanently leaving protocols unregistered for the life of the process. sd-server calls init_networking() right after Core::new(), so it's the client most exposed to this. Symptom: pairing over the web UI returns "Pairing protocol not registered" while the same library works fine from Tauri and mobile. Fix: init_networking now queries the registry directly for the pairing handler and re-registers the default set if it's missing, independent of whether networking is already initialized. Co-Authored-By: Claude Opus 4.7 (1M context) --- core/src/lib.rs | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/core/src/lib.rs b/core/src/lib.rs index 33a92292b..5d5cf8c21 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -520,10 +520,27 @@ impl Core { // Register protocols and set up event bridge if let Some(networking_service) = self.services.networking() { - // Register default protocol handlers only if networking was just initialized - // (if networking was already initialized during Core::new(), protocols are already registered) - if !already_initialized { - logger.info("Registering protocol handlers...").await; + // Core::new() attempts to register default protocols after starting + // networking, but swallows errors (only logs them). That means + // `already_initialized` does NOT imply protocols are registered — + // e.g. if the event loop's command sender wasn't ready when Core::new() + // tried to build the pairing handler, registration silently failed. + // Check the registry directly and re-register if missing. + let pairing_registered = networking_service + .protocol_registry() + .read() + .await + .get_handler("pairing") + .is_some(); + + if !already_initialized || !pairing_registered { + if already_initialized && !pairing_registered { + logger + .warn("Networking was initialized but protocol handlers are missing; re-registering") + .await; + } else { + logger.info("Registering protocol handlers...").await; + } self.register_default_protocols(&networking_service).await?; } else { logger