From e119cfb4682189980d058dd1d7b8316d5054b067 Mon Sep 17 00:00:00 2001 From: Kenny Lee Date: Mon, 26 Jan 2026 15:17:17 -0800 Subject: [PATCH] fix(macos): disable gateway launchd job when switching to remote mode Previously the stop() function had an early return when in remote mode, which skipped disabling the launchd job. This caused the gateway daemon to restart every 10 seconds due to KeepAlive, logging repeated 'Gateway start blocked' messages. Fixes #2433 --- CHANGELOG.md | 1 + apps/macos/Sources/Clawdbot/GatewayLaunchAgentManager.swift | 6 ++++-- apps/macos/Sources/Clawdbot/GatewayProcessManager.swift | 5 ++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a45315b20..614a47cca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,7 @@ Status: unreleased. - **BREAKING:** Gateway auth mode "none" is removed; gateway now requires token/password (Tailscale Serve identity still allowed). ### Fixes +- macOS: disable gateway launchd job when switching to remote mode. (#2433) - Security: pin npm overrides to keep tar@7.5.4 for install toolchains. - BlueBubbles: coalesce inbound URL link preview messages. (#1981) Thanks @tyler6204. - Agents: include memory.md when bootstrapping memory context. (#2318) Thanks @czekaj. diff --git a/apps/macos/Sources/Clawdbot/GatewayLaunchAgentManager.swift b/apps/macos/Sources/Clawdbot/GatewayLaunchAgentManager.swift index f0896e691..400aa43e6 100644 --- a/apps/macos/Sources/Clawdbot/GatewayLaunchAgentManager.swift +++ b/apps/macos/Sources/Clawdbot/GatewayLaunchAgentManager.swift @@ -51,8 +51,10 @@ enum GatewayLaunchAgentManager { static func set(enabled: Bool, bundlePath: String, port: Int) async -> String? { _ = bundlePath - guard !CommandResolver.connectionModeIsRemote() else { - self.logger.info("launchd change skipped (remote mode)") + // In remote mode, skip enabling (the local gateway shouldn't run), but still + // allow disabling so the launchd job stops retrying every 10 seconds. + if enabled, CommandResolver.connectionModeIsRemote() { + self.logger.info("launchd enable skipped (remote mode)") return nil } if enabled, self.isLaunchAgentWriteDisabled() { diff --git a/apps/macos/Sources/Clawdbot/GatewayProcessManager.swift b/apps/macos/Sources/Clawdbot/GatewayProcessManager.swift index 60964fa39..1356851bd 100644 --- a/apps/macos/Sources/Clawdbot/GatewayProcessManager.swift +++ b/apps/macos/Sources/Clawdbot/GatewayProcessManager.swift @@ -129,9 +129,8 @@ final class GatewayProcessManager { self.lastFailureReason = nil self.status = .stopped self.logger.info("gateway stop requested") - if CommandResolver.connectionModeIsRemote() { - return - } + // Always disable the launchd job, even in remote mode. Otherwise the job + // keeps restarting the gateway daemon every 10 seconds (KeepAlive throttle). let bundlePath = Bundle.main.bundleURL.path Task { _ = await GatewayLaunchAgentManager.set(