Problem
On macOS, hermes gateway start can create a second local gateway process when the launchd plist needs refreshing.
Root cause
refresh_launchd_plist_if_needed() unloads and reloads the launchd plist. Because the plist also has RunAtLoad, the reload already starts the gateway again. launchd_start() then unconditionally calls launchctl start, which can race a second local gateway process into existence.
Impact
That duplicate local process can grab Telegram/Discord/WhatsApp scoped locks and produce self-conflicts like:
- Telegram polling conflicts / token lock
- Discord token already in use
- WhatsApp session already in use
Suggested fix
If the plist was refreshed via unload+load, return early from launchd_start() instead of issuing a second explicit launchctl start.
Problem
On macOS,
hermes gateway startcan create a second local gateway process when the launchd plist needs refreshing.Root cause
refresh_launchd_plist_if_needed()unloads and reloads the launchd plist. Because the plist also hasRunAtLoad, the reload already starts the gateway again.launchd_start()then unconditionally callslaunchctl start, which can race a second local gateway process into existence.Impact
That duplicate local process can grab Telegram/Discord/WhatsApp scoped locks and produce self-conflicts like:
Suggested fix
If the plist was refreshed via unload+load, return early from
launchd_start()instead of issuing a second explicitlaunchctl start.