fix(windows): prevent restart race from duplicate schtasks /Run#52487
fix(windows): prevent restart race from duplicate schtasks /Run#52487andyk-ms wants to merge 2 commits intoopenclaw:mainfrom
Conversation
When CLI runs 'openclaw gateway restart', it does schtasks /End then schtasks /Run. Meanwhile the dying gateway fires a self-restart script (relaunchGatewayScheduledTask) that also retries schtasks /Run up to 12 times. Both succeed, creating duplicate gateway windows. Fix: the self-restart .cmd script now checks if the task is already running before attempting schtasks /Run. If another restart (CLI) beat it there, the script exits cleanly instead of spawning a duplicate. Fixes openclaw#52044
Greptile SummaryThis PR fixes the "triple window" bug on Windows by inserting a pre-flight Key changes:
Notable concern:
Confidence Score: 4/5
Prompt To Fix All With AIThis is a comment left during a code review.
Path: src/infra/windows-task-restart.ts
Line: 32-33
Comment:
**`findstr "Running"` is locale-sensitive**
`schtasks /Query /FO LIST` outputs localised status strings on non-English Windows installations (e.g. German "Wird ausgeführt", French "En cours d'exécution"). On those systems `findstr /I "Running"` will never match, so the early-exit guard silently does nothing and the script falls back to the original retry-12-times behaviour — leaving the duplicate-window bug present for non-English users.
A locale-independent alternative is to use PowerShell's `Get-ScheduledTask`, whose `.State` property is always an English enum value regardless of OS locale:
```
`powershell -Command "(Get-ScheduledTask -TaskName ${quotedTaskName} -ErrorAction SilentlyContinue).State" 2>nul | findstr /I "Running" >nul 2>&1`,
```
Or, if PowerShell is undesirable, check the exit code of `schtasks /Run` for the specific HRESULT `0x41301` ("task is already running") rather than querying status first — though that code isn't easily testable from a plain batch script.
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "fix(windows): prevent restart race from ..." | Re-trigger Greptile |
src/infra/windows-task-restart.ts
Outdated
| `schtasks /Query /TN ${quotedTaskName} /FO LIST 2>nul | findstr /I "Running" >nul 2>&1`, | ||
| "if not errorlevel 1 goto cleanup", |
There was a problem hiding this comment.
findstr "Running" is locale-sensitive
schtasks /Query /FO LIST outputs localised status strings on non-English Windows installations (e.g. German "Wird ausgeführt", French "En cours d'exécution"). On those systems findstr /I "Running" will never match, so the early-exit guard silently does nothing and the script falls back to the original retry-12-times behaviour — leaving the duplicate-window bug present for non-English users.
A locale-independent alternative is to use PowerShell's Get-ScheduledTask, whose .State property is always an English enum value regardless of OS locale:
`powershell -Command "(Get-ScheduledTask -TaskName ${quotedTaskName} -ErrorAction SilentlyContinue).State" 2>nul | findstr /I "Running" >nul 2>&1`,
Or, if PowerShell is undesirable, check the exit code of schtasks /Run for the specific HRESULT 0x41301 ("task is already running") rather than querying status first — though that code isn't easily testable from a plain batch script.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/infra/windows-task-restart.ts
Line: 32-33
Comment:
**`findstr "Running"` is locale-sensitive**
`schtasks /Query /FO LIST` outputs localised status strings on non-English Windows installations (e.g. German "Wird ausgeführt", French "En cours d'exécution"). On those systems `findstr /I "Running"` will never match, so the early-exit guard silently does nothing and the script falls back to the original retry-12-times behaviour — leaving the duplicate-window bug present for non-English users.
A locale-independent alternative is to use PowerShell's `Get-ScheduledTask`, whose `.State` property is always an English enum value regardless of OS locale:
```
`powershell -Command "(Get-ScheduledTask -TaskName ${quotedTaskName} -ErrorAction SilentlyContinue).State" 2>nul | findstr /I "Running" >nul 2>&1`,
```
Or, if PowerShell is undesirable, check the exit code of `schtasks /Run` for the specific HRESULT `0x41301` ("task is already running") rather than querying status first — though that code isn't easily testable from a plain batch script.
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a830edaf61
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
src/infra/windows-task-restart.ts
Outdated
| "set /a attempts+=1", | ||
| // Check if the task is already running (e.g. CLI restart beat us to it). | ||
| // schtasks /Query output contains "Running" when the task is active. | ||
| `schtasks /Query /TN ${quotedTaskName} /FO LIST 2>nul | findstr /I "Running" >nul 2>&1`, |
There was a problem hiding this comment.
Avoid locale-dependent running check in restart helper
This findstr /I "Running" guard depends on English schtasks output, but Windows localizes task status text, so on non-English installs the helper will miss the "already running" case and still execute /Run, allowing the duplicate-start race this patch is meant to prevent. Use a locale-invariant signal (for example Last Run Result code 0x41301) instead of matching an English token in the raw query output.
Useful? React with 👍 / 👎.
|
Addressed the locale-sensitivity feedback: replaced |
Problem
When
openclaw gateway restartruns, two sources race to start the task:schtasks /Endthenschtasks /RunrelaunchGatewayScheduledTask()which spawns a detached.cmdthat retriesschtasks /Runup to 12 timesBoth succeed, creating duplicate gateway windows (the "triple window" bug).
Fix
The self-restart
.cmdscript now queries the task status before attemptingschtasks /Run. If the task is already running (CLI beat it there), the script exits cleanly instead of spawning a duplicate.Impact
Fixes #52044