Skip to content

Bug: gateway LaunchAgent is sometimes removed from launchd domain and requires doctor/re-bootstrap #67335

Description

@ze1tgeist88

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions