diff --git a/packages/coding-agent/.changes/daemon-stop-detached-client.md b/packages/coding-agent/.changes/daemon-stop-detached-client.md new file mode 100644 index 000000000..422e83c97 --- /dev/null +++ b/packages/coding-agent/.changes/daemon-stop-detached-client.md @@ -0,0 +1 @@ +- Fixed stop and kill failing when the target worker's client had already disconnected. diff --git a/packages/coding-agent/src/modes/daemon/daemon-supervisor.ts b/packages/coding-agent/src/modes/daemon/daemon-supervisor.ts index c21e33b21..fa133cabe 100644 --- a/packages/coding-agent/src/modes/daemon/daemon-supervisor.ts +++ b/packages/coding-agent/src/modes/daemon/daemon-supervisor.ts @@ -6657,16 +6657,20 @@ export class DaemonSupervisor { worker.transcriptCaches.clear(); worker.snapshotCache.clear(); worker.snapshotGenerations?.clear(); - if (worker.client) { + const client = worker.client; + if (client) { if (archiveSession) { - await worker.client + await client .requestWorker({ type: "worker_archive_and_shutdown" }, force ? 1000 : 5000) .catch(() => undefined); } else { - await worker.client.request({ type: "shutdown" }, force ? 1000 : 5000).catch(() => undefined); + await client.request({ type: "shutdown" }, force ? 1000 : 5000).catch(() => undefined); + } + client.close(); + // A reconnect can swap in another client while the shutdown request is in flight. + if (worker.client === client) { + worker.client = undefined; } - worker.client.close(); - worker.client = undefined; } else if (directChild) { directChild.child.kill("SIGTERM"); } else if (this.processIdentity(entryPid, entryStartId) === "current") {