Skip to content

Commit 5189ba8

Browse files
committed
fix: stop windows startup fallback gateways
1 parent 5024fd0 commit 5189ba8

3 files changed

Lines changed: 53 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Docs: https://docs.openclaw.ai
2222
- Agents/memory bootstrap: load only one root memory file, preferring `MEMORY.md` and using `memory.md` as a fallback, so case-insensitive Docker mounts no longer inject duplicate memory context. (#26054) Thanks @Lanfei.
2323
- Agents/OpenAI-compatible compat overrides: respect explicit user `models[].compat` opt-ins for non-native `openai-completions` endpoints so usage-in-streaming capability overrides no longer get forced off when the endpoint actually supports them. (#44432) Thanks @cheapestinference.
2424
- Agents/Azure OpenAI startup prompts: rephrase the built-in `/new`, `/reset`, and post-compaction startup instruction so Azure OpenAI deployments no longer hit HTTP 400 false positives from the content filter. (#43403) Thanks @xingsy97.
25+
- Windows/gateway stop: resolve Startup-folder fallback listeners from the installed `gateway.cmd` port, so `openclaw gateway stop` now actually kills fallback-launched gateway processes before restart.
2526
- Config/validation: accept documented `agents.list[].params` per-agent overrides in strict config validation so `openclaw config validate` no longer rejects runtime-supported `cacheRetention`, `temperature`, and `maxTokens` settings. (#41171) Thanks @atian8179.
2627
- Android/onboarding QR scan: switch setup QR scanning to Google Code Scanner so onboarding uses a more reliable scanner instead of the legacy embedded ZXing flow. (#45021) Thanks @obviyus.
2728
- Config/web fetch: restore runtime validation for documented `tools.web.fetch.readability` and `tools.web.fetch.firecrawl` settings so valid web fetch configs no longer fail with unrecognized-key errors. (#42583) Thanks @stim64045-spec.

src/daemon/schtasks.startup-fallback.test.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const {
4343
readScheduledTaskRuntime,
4444
restartScheduledTask,
4545
resolveTaskScriptPath,
46+
stopScheduledTask,
4647
} = await import("./schtasks.js");
4748

4849
function resolveStartupEntryPath(env: Record<string, string>) {
@@ -74,6 +75,21 @@ async function withWindowsEnv(
7475
}
7576
}
7677

78+
async function writeGatewayScript(env: Record<string, string>, port = 18789) {
79+
const scriptPath = resolveTaskScriptPath(env);
80+
await fs.mkdir(path.dirname(scriptPath), { recursive: true });
81+
await fs.writeFile(
82+
scriptPath,
83+
[
84+
"@echo off",
85+
`set "OPENCLAW_GATEWAY_PORT=${port}"`,
86+
`"C:\\Program Files\\nodejs\\node.exe" "C:\\Users\\steipete\\AppData\\Roaming\\npm\\node_modules\\openclaw\\dist\\index.js" gateway --port ${port}`,
87+
"",
88+
].join("\r\n"),
89+
"utf8",
90+
);
91+
}
92+
7793
beforeEach(() => {
7894
schtasksResponses.length = 0;
7995
schtasksCalls.length = 0;
@@ -211,4 +227,39 @@ describe("Windows startup fallback", () => {
211227
);
212228
});
213229
});
230+
231+
it("kills the Startup fallback runtime even when the CLI env omits the gateway port", async () => {
232+
await withWindowsEnv(async ({ env }) => {
233+
schtasksResponses.push({ code: 0, stdout: "", stderr: "" });
234+
await writeGatewayScript(env);
235+
await fs.mkdir(path.dirname(resolveStartupEntryPath(env)), { recursive: true });
236+
await fs.writeFile(resolveStartupEntryPath(env), "@echo off\r\n", "utf8");
237+
inspectPortUsage
238+
.mockResolvedValueOnce({
239+
port: 18789,
240+
status: "busy",
241+
listeners: [{ pid: 5151, command: "node.exe" }],
242+
hints: [],
243+
})
244+
.mockResolvedValueOnce({
245+
port: 18789,
246+
status: "busy",
247+
listeners: [{ pid: 5151, command: "node.exe" }],
248+
hints: [],
249+
})
250+
.mockResolvedValueOnce({
251+
port: 18789,
252+
status: "free",
253+
listeners: [],
254+
hints: [],
255+
});
256+
257+
const stdout = new PassThrough();
258+
const envWithoutPort = { ...env };
259+
delete envWithoutPort.OPENCLAW_GATEWAY_PORT;
260+
await stopScheduledTask({ env: envWithoutPort, stdout });
261+
262+
expect(killProcessTree).toHaveBeenCalledWith(5151, { graceMs: 300 });
263+
});
264+
});
214265
});

src/daemon/schtasks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ async function terminateBusyPortListeners(port: number): Promise<number[]> {
482482
}
483483

484484
async function resolveFallbackRuntime(env: GatewayServiceEnv): Promise<GatewayServiceRuntime> {
485-
const port = resolveConfiguredGatewayPort(env);
485+
const port = (await resolveScheduledTaskPort(env)) ?? resolveConfiguredGatewayPort(env);
486486
if (!port) {
487487
return {
488488
status: "unknown",

0 commit comments

Comments
 (0)