Summary
Config changes (e.g., agents.list updates via config.patch) trigger a SIGTERM that kills the gateway process. On macOS with launchd, this creates a rapid restart loop that causes launchd to permanently remove the service, leaving the gateway dead with "Gateway service not loaded" error.
Environment
- OpenClaw: 2026.3.7
- macOS: Darwin 25.3.0 (arm64)
- Node: v25.5.0
- Service: LaunchAgent (ai.openclaw.gateway)
Steps to Reproduce
- Gateway running via launchd with
KeepAlive: true, ThrottleInterval: 1 (default plist from gateway install)
- Trigger a config change that touches
agents.list (e.g., updating an agent Slack permissions)
- Gateway logs show:
[reload] config change detected; evaluating reload (agents.list)
[reload] config change applied (dynamic reads: agents.list)
[gateway] signal SIGTERM received
[gateway] received SIGTERM; shutting down
- Launchd restarts the process within 1 second
- New process starts, detects same config change, dies again
- After ~7-10 rapid failures, launchd removes the service entirely
openclaw gateway restart now returns "Gateway service not loaded"
Expected Behavior
Config reloads should hot-reload without killing the gateway process. The gateway already logs config change applied (dynamic reads: agents.list) suggesting it can handle dynamic reloads, but something in the reload path sends SIGTERM anyway.
Workaround
Modified the launchd plist:
- Changed
KeepAlive from true to {SuccessfulExit: false} (only restart on crash, not clean exit)
- Changed
ThrottleInterval from 1 to 10 (give config changes time to settle)
This prevents launchd from giving up, but there is still a ~10 second gap on every config change where the gateway is down.
Launchd Logs (evidence of rapid failure loop)
10:16:20 service inactive: ai.openclaw.gateway
10:16:26 service inactive
10:16:32 service inactive
10:16:38 service inactive
10:16:44 service inactive
10:16:50 service inactive
10:16:56 service inactive
10:17:13 removing service: ai.openclaw.gateway
Impact
High. Users who manage agents via config changes (which is the normal workflow) will experience repeated gateway failures requiring manual intervention (gateway install in terminal, which itself creates a foreground/background conflict).
Summary
Config changes (e.g.,
agents.listupdates viaconfig.patch) trigger a SIGTERM that kills the gateway process. On macOS with launchd, this creates a rapid restart loop that causes launchd to permanently remove the service, leaving the gateway dead with "Gateway service not loaded" error.Environment
Steps to Reproduce
KeepAlive: true,ThrottleInterval: 1(default plist fromgateway install)agents.list(e.g., updating an agent Slack permissions)openclaw gateway restartnow returns "Gateway service not loaded"Expected Behavior
Config reloads should hot-reload without killing the gateway process. The gateway already logs
config change applied (dynamic reads: agents.list)suggesting it can handle dynamic reloads, but something in the reload path sends SIGTERM anyway.Workaround
Modified the launchd plist:
KeepAlivefromtrueto{SuccessfulExit: false}(only restart on crash, not clean exit)ThrottleIntervalfrom1to10(give config changes time to settle)This prevents launchd from giving up, but there is still a ~10 second gap on every config change where the gateway is down.
Launchd Logs (evidence of rapid failure loop)
Impact
High. Users who manage agents via config changes (which is the normal workflow) will experience repeated gateway failures requiring manual intervention (
gateway installin terminal, which itself creates a foreground/background conflict).