fix(gateway): handle CREATE_BREAKAWAY_FROM_JOB rejection on Windows /restart - #49043
Conversation
…restart When Hermes gateway runs under a Windows Scheduled Task, the process is inside a job object without JOB_OBJECT_LIMIT_BREAKAWAY_OK set. CREATE_BREAKAWAY_FROM_JOB (0x01000000) fails with ERROR_ACCESS_DENIED (WinError 5), and the restart watcher never starts — the bot goes silent until the watchdog respawns it minutes later. Fix: wrap the watcher subprocess.Popen in try/except OSError and retry with windows_detach_flags_without_breakaway() as fallback, matching the pattern already used in hermes_cli/gateway.py.
|
Duplicate of #42242 — both wrap the |
|
Thanks for the review — understood. This PR duplicates #42242, so I'll close it and defer to the earlier PR. Appreciate the confirmation that the underlying bug is still present on main. |
Problem
When the Hermes gateway is run via Windows Scheduled Task, running
/restarton Telegram causes the gateway to exit cleanly with no auto-restart — the bot goes silent until the watchdog cycle (up to 5 minutes) detects the outage and respawns the gateway.The root cause is in
_launch_detached_restart_command()(gateway/run.py): it spawns a Python watcher subprocess usingwindows_detach_popen_kwargs(), which includes theCREATE_BREAKAWAY_FROM_JOB(0x01000000) creation flag.When the gateway runs inside a job object that does not have
JOB_OBJECT_LIMIT_BREAKAWAY_OKset — which is the case for Windows Scheduled Tasks —CreateProcessreturnsERROR_ACCESS_DENIED(WinError 5). The watcher never starts, the gateway exits, and nothing respawns it until the watchdog kicks in minutes later.Fix
Wrap the watcher
subprocess.Popenin atry/except OSErrorblock. On failure:windows_detach_flags_without_breakaway()— which omitsCREATE_BREAKAWAY_FROM_JOBbut retainsDETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP | CREATE_NO_WINDOW.DETACHED_PROCESSalone is sufficient to survive the parent console closure in the Scheduled Task /pythonw.exescenario —BREAKAWAYis only needed when the parent is in an Electron/Tauri job object that tears down children on exit.Changes
gateway/run.py—_launch_detached_restart_command():windows_detach_flags_without_breakawayalongsidewindows_detach_popen_kwargssubprocess.Popenintry/except OSErrorwith a BREAKAWAY-less fallbackTesting
/restarton Telegram now successfully restarts the gateway within seconds instead of going silent for 5 minutes. Confirmed by gateway log: the watcher PID appears after the shutdown sequence.Related
The same pattern (try
BREAKAWAYfirst, fall back without) already exists inhermes_cli/gateway.pyandgateway_windows.py:_spawn_detached— this fix brings_launch_detached_restart_commandin line with the rest of the codebase.