From f3c143f0cd4ef0265b61aa332d791b75cacf758e Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 10 Apr 2026 21:30:07 +0100 Subject: [PATCH] fix(daemon): honor launchd running state without pid --- src/daemon/launchd.test.ts | 17 +++++++++++++++++ src/daemon/launchd.ts | 5 ++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/daemon/launchd.test.ts b/src/daemon/launchd.test.ts index 1a4819b9c1d..887aed55b98 100644 --- a/src/daemon/launchd.test.ts +++ b/src/daemon/launchd.test.ts @@ -554,6 +554,23 @@ describe("launchd install", () => { expect(output).toContain("did not fully stop the service"); }); + it("treats launchctl print state=running as running even when pid is missing", async () => { + const env = createDefaultLaunchdEnv(); + const stdout = new PassThrough(); + let output = ""; + state.stopLeavesRunning = true; + state.printOutput = "state = running\n"; + stdout.on("data", (chunk: Buffer) => { + output += chunk.toString(); + }); + + await stopLaunchAgent({ env, stdout }); + + expect(state.launchctlCalls.some((call) => call[0] === "bootout")).toBe(true); + expect(output).toContain("Stopped LaunchAgent (degraded)"); + expect(output).toContain("did not fully stop the service"); + }); + it("falls back to bootout when launchctl stop itself errors", async () => { const env = createDefaultLaunchdEnv(); const stdout = new PassThrough(); diff --git a/src/daemon/launchd.ts b/src/daemon/launchd.ts index a99f4a6c449..917525f46cf 100644 --- a/src/daemon/launchd.ts +++ b/src/daemon/launchd.ts @@ -519,7 +519,10 @@ async function probeLaunchAgentState(serviceTarget: string): Promise 1) { + if ( + normalizeLowercaseStringOrEmpty(runtime.state) === "running" || + (typeof runtime.pid === "number" && runtime.pid > 1) + ) { return { state: "running" }; } return { state: "stopped" };