Bug: gateway LaunchAgent is sometimes removed from launchd domain and requires doctor/re-bootstrap to come back
Summary
On macOS, the OpenClaw gateway process itself starts successfully, but the LaunchAgent job ai.openclaw.gateway is intermittently removed from the launchd GUI domain during OpenClaw-managed lifecycle flows. After some restart/config-change/bootstrap scenarios, the job no longer remains loaded across the expected lifecycle and later requires doctor or another re-bootstrap path to restore it.
This does not look like a gateway runtime crash. It looks like a service-management / launchd lifecycle bug.
Environment
- OpenClaw: 2026.4.14
- OS: macOS 26.4.1 arm64
- Node: 25.8.2
- Install path: Homebrew npm global install
- LaunchAgent label:
ai.openclaw.gateway
- User domain: GUI launchd user domain
What I expected
openclaw gateway restart or config-managed restarts should stop/start the gateway cleanly.
- The LaunchAgent should remain properly loaded in
launchd.
- After reboot/login, the gateway LaunchAgent should remain present and auto-start via
RunAtLoad + KeepAlive.
What happens instead
At various times, launchd logs show the service being removed from the GUI domain:
service inactive: ai.openclaw.gateway
removing service: ai.openclaw.gateway
Later, OpenClaw/CLI appears to re-bootstrap it again:
Setting service ai.openclaw.gateway to enabled ...
When this happens after reboot/login, the practical symptom is that the gateway is not up until doctor (or another CLI path) effectively re-installs / re-bootstraps the LaunchAgent.
Important observation
A normal openclaw gateway restart now appears to work fine in isolation. The bug seems tied to some OpenClaw-managed lifecycle paths such as:
- config rewrite / reload flows
- doctor-related service handling
- bootstrap / re-bootstrap service flows
- possibly reboot/login recovery behavior
So the issue appears to be service lifecycle persistence, not a failure of the gateway process to bind or start.
Evidence
LaunchAgent plist looks healthy
The LaunchAgent plist has:
RunAtLoad = true
KeepAlive = true
- valid
ProgramArguments
- valid stdout/stderr paths
launchctl state while healthy
launchctl print ... ai.openclaw.gateway
state = running
job state = running
last exit code = 0
launchd log pattern
Examples:
2026-04-15 18:13:37.928 ... service inactive: ai.openclaw.gateway
2026-04-15 18:13:37.928 ... removing service: ai.openclaw.gateway
2026-04-15 18:15:05.765 ... Setting service ai.openclaw.gateway to enabled ...
2026-04-15 20:16:25.935 ... service inactive: ai.openclaw.gateway
2026-04-15 20:16:25.935 ... removing service: ai.openclaw.gateway
2026-04-15 20:16:51.315 ... Setting service ai.openclaw.gateway to enabled ...
Gateway log pattern
The gateway usually receives a managed SIGTERM, then starts fine again:
[gateway] signal SIGTERM received
[gateway] received SIGTERM; shutting down
...
[gateway] loading configuration…
[gateway] resolving authentication…
[gateway] starting...
[gateway] starting HTTP server...
[gateway] ready
This suggests the process is healthy and the bug is in how OpenClaw manages launchd service lifecycle.
launchd initiator chain
launchd reports service enable operations initiated by launchctl <- node <- node <- shell <- ..., which points back to OpenClaw/CLI-managed service operations, not random launchd behavior.
Additional correlation
In many historical cases, SIGTERM/restart coincides with OpenClaw reload/config activity such as:
reload config change detected
reload config hot reload applied
- changes involving
agents.list, bindings, agents.defaults.model.primary, provider config, etc.
This may indicate that some config/service mutation path is escalating into a full launchd remove/bootstrap cycle.
Reproduction notes
This is not yet reduced to a single deterministic command sequence.
What has been observed:
- plain
openclaw gateway restart can succeed cleanly
- some other lifecycle path causes launchd to remove the job
- after reboot/login, the job may be absent until doctor/re-bootstrap is run
Hypothesis
OpenClaw's macOS service management occasionally performs a bootout/remove + bootstrap/enable sequence in cases where it should keep the LaunchAgent stably loaded, and that sequence is not always persistent/recoverable across reboot/login.
Requested fix
Please review the macOS LaunchAgent lifecycle logic around:
- gateway restart
- doctor / repair paths
- config-change-driven restart paths
- bootstrap/re-bootstrap logic
Specifically, I would check whether any code path unnecessarily removes the LaunchAgent from the GUI user domain instead of performing a stable restart, and whether reboot/login persistence is being re-established correctly after those flows.
Nice-to-have
- safer/idempotent launchd service management on macOS
- clearer logs when OpenClaw intentionally does
bootout / bootstrap
- a dedicated
openclaw gateway repair-launchagent or similar diagnostic/repair command
Bug: gateway LaunchAgent is sometimes removed from launchd domain and requires doctor/re-bootstrap to come back
Summary
On macOS, the OpenClaw gateway process itself starts successfully, but the LaunchAgent job
ai.openclaw.gatewayis intermittently removed from thelaunchdGUI domain during OpenClaw-managed lifecycle flows. After some restart/config-change/bootstrap scenarios, the job no longer remains loaded across the expected lifecycle and later requiresdoctoror another re-bootstrap path to restore it.This does not look like a gateway runtime crash. It looks like a service-management / launchd lifecycle bug.
Environment
ai.openclaw.gatewayWhat I expected
openclaw gateway restartor config-managed restarts should stop/start the gateway cleanly.launchd.RunAtLoad+KeepAlive.What happens instead
At various times, launchd logs show the service being removed from the GUI domain:
service inactive: ai.openclaw.gatewayremoving service: ai.openclaw.gatewayLater, OpenClaw/CLI appears to re-bootstrap it again:
Setting service ai.openclaw.gateway to enabled ...When this happens after reboot/login, the practical symptom is that the gateway is not up until
doctor(or another CLI path) effectively re-installs / re-bootstraps the LaunchAgent.Important observation
A normal
openclaw gateway restartnow appears to work fine in isolation. The bug seems tied to some OpenClaw-managed lifecycle paths such as:So the issue appears to be service lifecycle persistence, not a failure of the gateway process to bind or start.
Evidence
LaunchAgent plist looks healthy
The LaunchAgent plist has:
RunAtLoad = trueKeepAlive = trueProgramArgumentslaunchctl state while healthy
launchctl print ... ai.openclaw.gatewaystate = runningjob state = runninglast exit code = 0launchd log pattern
Examples:
Gateway log pattern
The gateway usually receives a managed SIGTERM, then starts fine again:
This suggests the process is healthy and the bug is in how OpenClaw manages launchd service lifecycle.
launchd initiator chain
launchd reports service enable operations initiated by
launchctl <- node <- node <- shell <- ..., which points back to OpenClaw/CLI-managed service operations, not random launchd behavior.Additional correlation
In many historical cases, SIGTERM/restart coincides with OpenClaw reload/config activity such as:
reload config change detectedreload config hot reload appliedagents.list,bindings,agents.defaults.model.primary, provider config, etc.This may indicate that some config/service mutation path is escalating into a full launchd remove/bootstrap cycle.
Reproduction notes
This is not yet reduced to a single deterministic command sequence.
What has been observed:
openclaw gateway restartcan succeed cleanlyHypothesis
OpenClaw's macOS service management occasionally performs a
bootout/remove + bootstrap/enablesequence in cases where it should keep the LaunchAgent stably loaded, and that sequence is not always persistent/recoverable across reboot/login.Requested fix
Please review the macOS LaunchAgent lifecycle logic around:
Specifically, I would check whether any code path unnecessarily removes the LaunchAgent from the GUI user domain instead of performing a stable restart, and whether reboot/login persistence is being re-established correctly after those flows.
Nice-to-have
bootout/bootstrapopenclaw gateway repair-launchagentor similar diagnostic/repair command