Repository navigation
fix(whatsapp): fall back when the parent job forbids CREATE_BREAKAWAY_FROM_JOB - #132463
ConTresillo wants to merge 1 commit into
Conversation
…_FROM_JOB The Baileys bridge is spawned with windows_detach_popen_kwargs(), whose default Windows flags include CREATE_BREAKAWAY_FROM_JOB. Per MSDN, that flag is only valid when the parent's job object sets JOB_OBJECT_LIMIT_BREAKAWAY_OK; otherwise CreateProcess fails with ERROR_ACCESS_DENIED (WinError 5). Electron (Hermes Desktop) and Task Scheduler both wrap children in jobs that do not grant breakaway, so on Windows the bridge could never start from either launch path and WhatsApp stayed permanently "Disconnected". Observed on Windows 10 with Hermes_Gateway (Task Scheduler) and a Desktop-initiated restart; the live gateway's job reported LimitFlags=0x0. Catch PermissionError and retry with windows_detach_flags_without_breakaway() — the fallback already documented in _subprocess_compat.windows_detach_flags but not used by this caller. The retry keeps the bridge in the gateway's job, so it now dies with the gateway instead of outliving it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This appears to duplicate #87777, which already implements the same no-breakaway retry and includes regression coverage. |
Fix direction is right, and I confirmed the premise rather than assuming it: 1. Narrow the
That guard applies to you. So: unwritable cache dir → except PermissionError as exc:
if getattr(exc, "winerror", None) != 5:
raise2. No regression test — and this branch is invisible to CI.
Minor: Verified against base |
Problem
On Windows, the WhatsApp (Baileys) bridge could never start when the gateway was launched from Hermes Desktop or from Task Scheduler. The platform showed permanently "Disconnected" and every reconnect attempt failed:
Cause
The bridge is spawned with
windows_detach_popen_kwargs(), whose default Windows flags includeCREATE_BREAKAWAY_FROM_JOB. Per MSDN:Electron (Hermes Desktop) and Task Scheduler both wrap their children in job objects that do not grant breakaway, so
CreateProcessis rejected withERROR_ACCESS_DENIEDevery time. I confirmed this against a live gateway process: querying its job object returnedLimitFlags=0x0, i.e.JOB_OBJECT_LIMIT_BREAKAWAY_OKunset. Spawning the samenode bridge.js ...command outside that job succeeded, and node itself was fine — only the flag was rejected._subprocess_compat.windows_detach_flags()documents that "a job that forbids breakaway yields PermissionError from Popen — callers catch OSError and fall back towindows_detach_flags_without_breakaway", and that helper already exists. This caller was the one place not doing it.Fix
Catch
PermissionErroron the bridge spawn and retry withwindows_detach_flags_without_breakaway(), i.e. the same command withoutCREATE_BREAKAWAY_FROM_JOB. This is the documented fallback; no new helper is introduced.Verification
On Windows 10, gateway restarted via
Hermes_Gateway(Task Scheduler), log:bridge.log:✅ WhatsApp connected!— inbound and outbound messages flowing.Tradeoff
Without breakaway the bridge stays in the gateway's job, so if the gateway is killed the bridge dies with it instead of surviving. For a long-running gateway this is not meaningful, and the alternative is WhatsApp never connecting at all on Desktop/Task Scheduler launches.
Scope note
This is not WhatsApp-specific.
windows_detach_popen_kwargs()is the default detach path repo-wide, so any other adapter that spawns a helper process under Electron or Task Scheduler will hit the same wall. This PR fixes the WhatsApp adapter only; a repo-wide sweep of othersubprocess.Popen(..., **windows_detach_popen_kwargs())call sites may be worth a separate pass.🤖 Generated with Claude Code